Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af675a32b8 | ||
|
|
5136a67fba | ||
|
|
18c2f0f00b | ||
|
|
3a194f2616 | ||
|
|
2611ab62d5 | ||
|
|
748feabf24 | ||
|
|
14ea92dab9 | ||
|
|
92847e87aa | ||
|
|
f372cbe8ab | ||
|
|
d93581fad6 |
@@ -4,7 +4,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>backlib</artifactId>
|
<artifactId>backlib</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>23</maven.compiler.source>
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
@@ -24,11 +24,11 @@
|
|||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<repository>
|
<repository>
|
||||||
<id>gitea</id>
|
<id>MiarmaGit</id>
|
||||||
<url>https://git.miarma.net/api/packages/Gallardo7761/maven</url>
|
<url>https://git.miarma.net/api/packages/Gallardo7761/maven</url>
|
||||||
</repository>
|
</repository>
|
||||||
<snapshotRepository>
|
<snapshotRepository>
|
||||||
<id>gitea</id>
|
<id>MiarmaGit</id>
|
||||||
<url>https://git.miarma.net/api/packages/Gallardo7761/maven</url>
|
<url>https://git.miarma.net/api/packages/Gallardo7761/maven</url>
|
||||||
</snapshotRepository>
|
</snapshotRepository>
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
@@ -132,33 +132,4 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>BackLib</finalName>
|
|
||||||
<plugins>
|
|
||||||
<!-- Maven Shade Plugin -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.5.3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<transformers>
|
|
||||||
<transformer
|
|
||||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
|
||||||
<mainClass>net.miarma.backlib.MainVerticle</mainClass>
|
|
||||||
</transformer>
|
|
||||||
</transformers>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,469 +0,0 @@
|
|||||||
package net.miarma.api.backlib;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import net.miarma.api.backlib.gson.APIDontReturnExclusionStrategy;
|
|
||||||
import net.miarma.api.backlib.gson.JsonObjectTypeAdapter;
|
|
||||||
import net.miarma.api.backlib.gson.LocalDateTimeAdapter;
|
|
||||||
import net.miarma.api.backlib.gson.ValuableEnumDeserializer;
|
|
||||||
import net.miarma.api.backlib.gson.ValuableEnumTypeAdapter;
|
|
||||||
import net.miarma.api.backlib.interfaces.IUserRole;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clase que contiene constantes y enumeraciones utilizadas en la API de MiarmaCore.
|
|
||||||
* @author José Manuel Amador Gallardo
|
|
||||||
*/
|
|
||||||
public class Constants {
|
|
||||||
public static final String APP_NAME = "MiarmaCoreAPI";
|
|
||||||
public static final String BASE_PREFIX = "/api";
|
|
||||||
public static final String CORE_PREFIX = BASE_PREFIX + "/core/v1"; // tabla de usuarios central
|
|
||||||
public static final String AUTH_PREFIX = "/auth/v1";
|
|
||||||
public static final String HUERTOS_PREFIX = BASE_PREFIX + "/huertos/v1";
|
|
||||||
public static final String MMC_PREFIX = BASE_PREFIX + "/mmc/v1";
|
|
||||||
public static final String CINE_PREFIX = BASE_PREFIX + "/cine/v1";
|
|
||||||
public static final String MPASTE_PREFIX = BASE_PREFIX + "/mpaste/v1";
|
|
||||||
|
|
||||||
public static final String AUTH_EVENT_BUS = "auth.eventbus";
|
|
||||||
public static final String CORE_EVENT_BUS = "core.eventbus";
|
|
||||||
public static final String HUERTOS_EVENT_BUS = "huertos.eventbus";
|
|
||||||
public static final String MMC_EVENT_BUS = "mmc.eventbus";
|
|
||||||
public static final String CINE_EVENT_BUS = "cine.eventbus";
|
|
||||||
public static final String MPASTE_EVENT_BUS = "mpaste.eventbus";
|
|
||||||
|
|
||||||
public static final List<String> HUERTOS_ALLOWED_FOLDERS =
|
|
||||||
List.of("INBOX", "Drafts", "Sent", "Spam", "Trash");
|
|
||||||
|
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger(Constants.APP_NAME);
|
|
||||||
|
|
||||||
public static final Gson GSON = new GsonBuilder()
|
|
||||||
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
|
|
||||||
.registerTypeAdapter(JsonObject.class, new JsonObjectTypeAdapter())
|
|
||||||
.registerTypeHierarchyAdapter(ValuableEnum.class, new ValuableEnumTypeAdapter())
|
|
||||||
.registerTypeAdapter(CoreUserGlobalStatus.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(CoreUserRole.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosUserType.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosUserStatus.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosUserRole.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosRequestStatus.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosRequestType.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosPaymentType.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosPaymentFrequency.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(HuertosAnnouncePriority.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(MMCUserStatus.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(MMCUserRole.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(CoreFileContext.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(MMCModStatus.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(CineUserRole.class, new ValuableEnumDeserializer())
|
|
||||||
.registerTypeAdapter(CineUserStatus.class, new ValuableEnumDeserializer())
|
|
||||||
.addSerializationExclusionStrategy(new APIDontReturnExclusionStrategy())
|
|
||||||
.create();
|
|
||||||
|
|
||||||
public enum CoreUserRole implements IUserRole {
|
|
||||||
USER(0),
|
|
||||||
ADMIN(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
CoreUserRole(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CoreUserRole fromInt(int i) {
|
|
||||||
for (CoreUserRole role : values()) {
|
|
||||||
if (role.value == i) return role;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid CoreUserRole value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum CoreUserGlobalStatus implements ValuableEnum {
|
|
||||||
INACTIVE(0),
|
|
||||||
ACTIVE(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
CoreUserGlobalStatus(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CoreUserGlobalStatus fromInt(int i) {
|
|
||||||
for (CoreUserGlobalStatus status : values()) {
|
|
||||||
if (status.value == i) return status;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid CoreUserGlobalStatus value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CoreFileContext implements ValuableEnum {
|
|
||||||
CORE(0),
|
|
||||||
HUERTOS(1),
|
|
||||||
MMC(2),
|
|
||||||
CINE(3);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
CoreFileContext(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toCtxString() {
|
|
||||||
return switch(this) {
|
|
||||||
case CORE -> "core";
|
|
||||||
case HUERTOS -> "huertos";
|
|
||||||
case MMC -> "miarmacraft";
|
|
||||||
case CINE -> "cine";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CoreFileContext fromInt(int i) {
|
|
||||||
for (CoreFileContext context : values()) {
|
|
||||||
if (context.value == i) return context;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid CoreFileContext value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum HuertosUserRole implements IUserRole {
|
|
||||||
USER(0),
|
|
||||||
ADMIN(1),
|
|
||||||
DEV(2);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosUserRole(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosUserRole fromInt(int i) {
|
|
||||||
for (HuertosUserRole role : values()) {
|
|
||||||
if (role.value == i) return role;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertosUserRole value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum HuertosUserType implements ValuableEnum {
|
|
||||||
WAIT_LIST(0),
|
|
||||||
MEMBER(1),
|
|
||||||
WITH_GREENHOUSE(2),
|
|
||||||
COLLABORATOR(3),
|
|
||||||
DEVELOPER(5),
|
|
||||||
SUBSIDY(4);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosUserType(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosUserType fromInt(int i) {
|
|
||||||
for (HuertosUserType type : values()) {
|
|
||||||
if (type.value == i) return type;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertosUserType value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum HuertosUserStatus implements ValuableEnum {
|
|
||||||
INACTIVE(0),
|
|
||||||
ACTIVE(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosUserStatus(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosUserStatus fromInt(int i) {
|
|
||||||
for (HuertosUserStatus status : values()) {
|
|
||||||
if (status.value == i) return status;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertosUserStatus value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum HuertosRequestStatus implements ValuableEnum {
|
|
||||||
PENDING(0),
|
|
||||||
APPROVED(1),
|
|
||||||
REJECTED(2);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosRequestStatus(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosRequestStatus fromInt(int i) {
|
|
||||||
for (HuertosRequestStatus status : values()) {
|
|
||||||
if (status.value == i) return status;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertoRequestStatus value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum HuertosPaymentType implements ValuableEnum {
|
|
||||||
BANK(0),
|
|
||||||
CASH(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosPaymentType(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosPaymentType fromInt(int i) {
|
|
||||||
for (HuertosPaymentType type : values()) {
|
|
||||||
if (type.value == i) return type;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertoPaymentType value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum HuertosRequestType implements ValuableEnum {
|
|
||||||
REGISTER(0),
|
|
||||||
UNREGISTER(1),
|
|
||||||
ADD_COLLABORATOR(2),
|
|
||||||
REMOVE_COLLABORATOR(3),
|
|
||||||
ADD_GREENHOUSE(4),
|
|
||||||
REMOVE_GREENHOUSE(5);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosRequestType(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosRequestType fromInt(int i) {
|
|
||||||
for (HuertosRequestType type : values()) {
|
|
||||||
if (type.value == i) return type;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertoRequestType value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum HuertosAnnouncePriority implements ValuableEnum {
|
|
||||||
LOW(0),
|
|
||||||
MEDIUM(1),
|
|
||||||
HIGH(2);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosAnnouncePriority(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosAnnouncePriority fromInt(int i) {
|
|
||||||
for (HuertosAnnouncePriority priority : values()) {
|
|
||||||
if (priority.value == i) return priority;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertoAnnouncePriority value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum HuertosPaymentFrequency implements ValuableEnum {
|
|
||||||
BIYEARLY(0),
|
|
||||||
YEARLY(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
HuertosPaymentFrequency(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HuertosPaymentFrequency fromInt(int i) {
|
|
||||||
for (HuertosPaymentFrequency frequency : values()) {
|
|
||||||
if (frequency.value == i) return frequency;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid HuertoPaymentFrequency value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum MMCUserRole implements IUserRole {
|
|
||||||
PLAYER(0),
|
|
||||||
ADMIN(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
MMCUserRole(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MMCUserRole fromInt(int i) {
|
|
||||||
for (MMCUserRole role : values()) {
|
|
||||||
if (role.value == i) return role;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid MMCUserRole value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public enum MMCUserStatus implements ValuableEnum {
|
|
||||||
INACTIVE(0),
|
|
||||||
ACTIVE(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
MMCUserStatus(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MMCUserStatus fromInt(int i) {
|
|
||||||
for (MMCUserStatus status : values()) {
|
|
||||||
if (status.value == i) return status;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid MMCUserStatus value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum MMCModStatus implements ValuableEnum {
|
|
||||||
ACTIVE(0),
|
|
||||||
INACTIVE(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
MMCModStatus(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MMCModStatus fromInt(int i) {
|
|
||||||
for (MMCModStatus status : values()) {
|
|
||||||
if (status.value == i) return status;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid MiarmacraftModStatus value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CineUserStatus implements ValuableEnum {
|
|
||||||
ACTIVE(1),
|
|
||||||
INACTIVE(0);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
CineUserStatus(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CineUserStatus fromInt(int i) {
|
|
||||||
for (CineUserStatus status : values()) {
|
|
||||||
if (status.value == i) return status;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid CineUserStatus value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CineUserRole implements IUserRole {
|
|
||||||
USER(0),
|
|
||||||
ADMIN(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
CineUserRole(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CineUserRole fromInt(int i) {
|
|
||||||
for (CineUserRole role : values()) {
|
|
||||||
if (role.value == i) return role;
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Invalid CineUserRole value: " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private constructor to prevent instantiation
|
|
||||||
private Constants() {
|
|
||||||
throw new AssertionError("Utility class cannot be instantiated.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.backlib;
|
package net.miarma.api.backlib.config;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -8,6 +8,10 @@ import java.io.InputStreamReader;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gestión de toda la configuración de la aplicación.
|
* Gestión de toda la configuración de la aplicación.
|
||||||
* Se encarga de cargar, guardar y proporcionar acceso a las propiedades de configuración.
|
* Se encarga de cargar, guardar y proporcionar acceso a las propiedades de configuración.
|
||||||
@@ -19,14 +23,16 @@ import java.util.Properties;
|
|||||||
*/
|
*/
|
||||||
public class ConfigManager {
|
public class ConfigManager {
|
||||||
private static ConfigManager instance;
|
private static ConfigManager instance;
|
||||||
|
private final String appName;
|
||||||
private final File configFile;
|
private final File configFile;
|
||||||
private final Properties config;
|
private final Properties config;
|
||||||
private static final String CONFIG_FILE_NAME = "config.properties";
|
private static final String CONFIG_FILE_NAME = "config.properties";
|
||||||
|
private final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
|
|
||||||
private ConfigManager() {
|
private ConfigManager() {
|
||||||
String path = getBaseDir() + CONFIG_FILE_NAME;
|
this.appName = System.getenv().getOrDefault("APP_NAME", "miarma-backend");
|
||||||
this.configFile = new File(path);
|
|
||||||
this.config = new Properties();
|
this.config = new Properties();
|
||||||
|
this.configFile = new File(getBaseDir() + CONFIG_FILE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized ConfigManager getInstance() {
|
public static synchronized ConfigManager getInstance() {
|
||||||
@@ -41,7 +47,7 @@ public class ConfigManager {
|
|||||||
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8)) {
|
InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8)) {
|
||||||
config.load(isr);
|
config.load(isr);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Constants.LOGGER.error("Error loading configuration file: ", e);
|
LOGGER.error("Error loading configuration file: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public File getConfigFile() {
|
public File getConfigFile() {
|
||||||
@@ -118,6 +124,11 @@ public class ConfigManager {
|
|||||||
return Boolean.parseBoolean(System.getenv("RUNNING_IN_DOCKER"));
|
return Boolean.parseBoolean(System.getenv("RUNNING_IN_DOCKER"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getApiPrefix(String domain) {
|
||||||
|
return getStringProperty("api." + domain + ".prefix").replace("${app.version}",
|
||||||
|
String.valueOf(getStringProperty("app.version")));
|
||||||
|
}
|
||||||
|
|
||||||
public String getStringProperty(String key) {
|
public String getStringProperty(String key) {
|
||||||
return config.getProperty(key);
|
return config.getProperty(key);
|
||||||
}
|
}
|
||||||
@@ -138,9 +149,9 @@ public class ConfigManager {
|
|||||||
|
|
||||||
private void saveConfig() {
|
private void saveConfig() {
|
||||||
try (FileOutputStream fos = new FileOutputStream(configFile)) {
|
try (FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||||
config.store(fos, "Configuration for: " + Constants.APP_NAME);
|
config.store(fos, "Configuration for: " + this.appName);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Constants.LOGGER.error("Error saving configuration file: ", e);
|
LOGGER.error("Error saving configuration file: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.backlib;
|
package net.miarma.api.backlib.config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum que representa los diferentes tipos de sistemas operativos soportados
|
* Enum que representa los diferentes tipos de sistemas operativos soportados
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package net.miarma.api.backlib.core.entities;
|
|
||||||
|
|
||||||
import io.vertx.sqlclient.Row;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreFileContext;
|
|
||||||
import net.miarma.api.backlib.annotations.Table;
|
|
||||||
import net.miarma.api.backlib.db.AbstractEntity;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
@Table("files")
|
|
||||||
public class FileEntity extends AbstractEntity {
|
|
||||||
private Integer file_id;
|
|
||||||
private String file_name;
|
|
||||||
private String file_path;
|
|
||||||
private String mime_type;
|
|
||||||
private Integer uploaded_by;
|
|
||||||
private CoreFileContext context;
|
|
||||||
private LocalDateTime uploaded_at;
|
|
||||||
|
|
||||||
public FileEntity() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileEntity(Row row) {
|
|
||||||
super(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getFile_id() {
|
|
||||||
return file_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFile_id(Integer file_id) {
|
|
||||||
this.file_id = file_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFile_name() {
|
|
||||||
return file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFile_name(String file_name) {
|
|
||||||
this.file_name = file_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFile_path() {
|
|
||||||
return file_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFile_path(String file_path) {
|
|
||||||
this.file_path = file_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMime_type() {
|
|
||||||
return mime_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMime_type(String mime_type) {
|
|
||||||
this.mime_type = mime_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getUploaded_by() {
|
|
||||||
return uploaded_by;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUploaded_by(Integer uploaded_by) {
|
|
||||||
this.uploaded_by = uploaded_by;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CoreFileContext getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(CoreFileContext context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getUploaded_at() {
|
|
||||||
return uploaded_at;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUploaded_at(LocalDateTime uploaded_at) {
|
|
||||||
this.uploaded_at = uploaded_at;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package net.miarma.api.backlib.core.entities;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import io.vertx.sqlclient.Row;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserGlobalStatus;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
|
||||||
import net.miarma.api.backlib.annotations.APIDontReturn;
|
|
||||||
import net.miarma.api.backlib.annotations.Table;
|
|
||||||
import net.miarma.api.backlib.db.AbstractEntity;
|
|
||||||
import net.miarma.api.backlib.interfaces.IUser;
|
|
||||||
|
|
||||||
@Table("users")
|
|
||||||
public class UserEntity extends AbstractEntity implements IUser {
|
|
||||||
private Integer user_id;
|
|
||||||
private String user_name;
|
|
||||||
private String email;
|
|
||||||
private String display_name;
|
|
||||||
@APIDontReturn
|
|
||||||
private String password;
|
|
||||||
private String avatar;
|
|
||||||
private CoreUserGlobalStatus global_status;
|
|
||||||
private CoreUserRole role;
|
|
||||||
private LocalDateTime created_at;
|
|
||||||
private LocalDateTime updated_at;
|
|
||||||
|
|
||||||
public UserEntity() { }
|
|
||||||
public UserEntity(Row row) { super(row); }
|
|
||||||
|
|
||||||
public Integer getUser_id() { return user_id; }
|
|
||||||
public void setUser_id(Integer user_id) { this.user_id = user_id; }
|
|
||||||
public String getUser_name() { return user_name; }
|
|
||||||
public void setUser_name(String user_name) { this.user_name = user_name; }
|
|
||||||
public String getEmail() { return email; }
|
|
||||||
public void setEmail(String email) { this.email = email; }
|
|
||||||
public String getDisplay_name() { return display_name; }
|
|
||||||
public void setDisplay_name(String display_name) { this.display_name = display_name; }
|
|
||||||
public String getPassword() { return password; }
|
|
||||||
public void setPassword(String password) { this.password = password; }
|
|
||||||
public String getAvatar() { return avatar; }
|
|
||||||
public void setAvatar(String avatar) { this.avatar = avatar; }
|
|
||||||
public CoreUserGlobalStatus getGlobal_status() { return global_status; }
|
|
||||||
public void setGlobal_status(CoreUserGlobalStatus global_status) { this.global_status = global_status; }
|
|
||||||
public CoreUserRole getGlobal_role() { return role; }
|
|
||||||
public void setGlobal_role(CoreUserRole role) { this.role = role; }
|
|
||||||
public LocalDateTime getCreated_at() { return created_at; }
|
|
||||||
public void setCreated_at(LocalDateTime created_at) { this.created_at = created_at; }
|
|
||||||
public LocalDateTime getUpdated_at() { return updated_at; }
|
|
||||||
public void setUpdated_at(LocalDateTime updated_at) { this.updated_at = updated_at; }
|
|
||||||
|
|
||||||
public static UserEntity from(IUser user) {
|
|
||||||
UserEntity entity = new UserEntity();
|
|
||||||
entity.setUser_id(user.getUser_id());
|
|
||||||
entity.setUser_name(user.getUser_name());
|
|
||||||
entity.setDisplay_name(user.getDisplay_name());
|
|
||||||
entity.setEmail(user.getEmail());
|
|
||||||
entity.setPassword(user.getPassword());
|
|
||||||
entity.setAvatar(user.getAvatar());
|
|
||||||
entity.setGlobal_status(user.getGlobal_status());
|
|
||||||
entity.setGlobal_role(user.getGlobal_role());
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
package net.miarma.api.backlib.core.handlers;
|
|
||||||
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
|
||||||
import io.vertx.sqlclient.Pool;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
|
||||||
import net.miarma.api.backlib.util.JsonUtil;
|
|
||||||
import net.miarma.api.backlib.core.entities.UserEntity;
|
|
||||||
import net.miarma.api.backlib.core.services.UserService;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class UserDataHandler {
|
|
||||||
|
|
||||||
private final UserService userService;
|
|
||||||
|
|
||||||
public UserDataHandler(Pool pool) {
|
|
||||||
this.userService = new UserService(pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getAll(RoutingContext ctx) {
|
|
||||||
QueryParams params = QueryParams.from(ctx);
|
|
||||||
|
|
||||||
userService.getAll(params)
|
|
||||||
.onSuccess(users -> JsonUtil.sendJson(ctx, ApiStatus.OK, users)).onFailure(err -> {
|
|
||||||
ApiStatus status = ApiStatus.fromException(err);
|
|
||||||
JsonUtil.sendJson(ctx, status, null, err.getMessage());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getById(RoutingContext ctx) {
|
|
||||||
Integer userId = Integer.parseInt(ctx.pathParam("user_id"));
|
|
||||||
|
|
||||||
userService.getById(userId)
|
|
||||||
.onSuccess(user -> JsonUtil.sendJson(ctx, ApiStatus.OK, user)).onFailure(err -> {
|
|
||||||
ApiStatus status = ApiStatus.fromException(err);
|
|
||||||
JsonUtil.sendJson(ctx, status, null, err.getMessage());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void create(RoutingContext ctx) {
|
|
||||||
UserEntity user = Constants.GSON.fromJson(ctx.body().asString(), UserEntity.class);
|
|
||||||
|
|
||||||
userService.register(user)
|
|
||||||
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result)).onFailure(err -> {
|
|
||||||
ApiStatus status = ApiStatus.fromException(err);
|
|
||||||
JsonUtil.sendJson(ctx, status, null, err.getMessage());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(RoutingContext ctx) {
|
|
||||||
UserEntity user = Constants.GSON.fromJson(ctx.body().asString(), UserEntity.class);
|
|
||||||
|
|
||||||
userService.update(user)
|
|
||||||
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, result)).onFailure(err -> {
|
|
||||||
ApiStatus status = ApiStatus.fromException(err);
|
|
||||||
JsonUtil.sendJson(ctx, status, null, err.getMessage());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete(RoutingContext ctx) {
|
|
||||||
Integer userId = Integer.parseInt(ctx.pathParam("user_id"));
|
|
||||||
|
|
||||||
userService.delete(userId)
|
|
||||||
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, result)).onFailure(err -> {
|
|
||||||
ApiStatus status = ApiStatus.fromException(err);
|
|
||||||
JsonUtil.sendJson(ctx, status, null, err.getMessage());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,286 +0,0 @@
|
|||||||
package net.miarma.api.backlib.core.handlers;
|
|
||||||
|
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
|
||||||
|
|
||||||
import io.vertx.core.Vertx;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
|
||||||
import net.miarma.api.backlib.security.JWTManager;
|
|
||||||
import net.miarma.api.backlib.util.EventBusUtil;
|
|
||||||
import net.miarma.api.backlib.util.JsonUtil;
|
|
||||||
import net.miarma.api.backlib.core.entities.UserEntity;
|
|
||||||
|
|
||||||
public class UserLogicHandler {
|
|
||||||
|
|
||||||
private final Vertx vertx;
|
|
||||||
|
|
||||||
public UserLogicHandler(Vertx vertx) {
|
|
||||||
this.vertx = vertx;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void login(RoutingContext ctx) {
|
|
||||||
JsonObject body = ctx.body().asJsonObject();
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "login")
|
|
||||||
.put("email", body.getString("email", null))
|
|
||||||
.put("userName", body.getString("userName", null))
|
|
||||||
.put("password", body.getString("password"))
|
|
||||||
.put("keepLoggedIn", body.getBoolean("keepLoggedIn", false));
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonObject result = (JsonObject) ar.result().body();
|
|
||||||
result.put("tokenTime", System.currentTimeMillis());
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, result);
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loginValidate(RoutingContext ctx) {
|
|
||||||
JsonObject body = ctx.body().asJsonObject();
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "loginValidate")
|
|
||||||
.put("userId", body.getInteger("userId"))
|
|
||||||
.put("password", body.getString("password"));
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register(RoutingContext ctx) {
|
|
||||||
JsonObject body = ctx.body().asJsonObject();
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "register")
|
|
||||||
.put("userName", body.getString("userName"))
|
|
||||||
.put("email", body.getString("email"))
|
|
||||||
.put("displayName", body.getString("displayName"))
|
|
||||||
.put("password", body.getString("password"));
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.CREATED, null);
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changePassword(RoutingContext ctx) {
|
|
||||||
JsonObject body = ctx.body().asJsonObject();
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "changePassword")
|
|
||||||
.put("userId", body.getInteger("userId"))
|
|
||||||
.put("newPassword", body.getString("newPassword"));
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, true, "Updated");
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validateToken(RoutingContext ctx) {
|
|
||||||
String authHeader = ctx.request().getHeader("Authorization");
|
|
||||||
|
|
||||||
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
|
||||||
String token = authHeader.substring(7);
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "validateToken")
|
|
||||||
.put("token", token);
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded() && Boolean.TRUE.equals(ar.result().body())) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, true, "Valid token");
|
|
||||||
} else {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, false, "Invalid token");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.BAD_REQUEST, null, "Missing or invalid Authorization header");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refreshToken(RoutingContext ctx) {
|
|
||||||
String tokenHeader = ctx.request().getHeader("Authorization");
|
|
||||||
|
|
||||||
if (tokenHeader == null || !tokenHeader.startsWith("Bearer ")) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Missing or invalid Authorization header");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String token = tokenHeader.substring("Bearer ".length());
|
|
||||||
JWTManager jwt = JWTManager.getInstance();
|
|
||||||
|
|
||||||
try {
|
|
||||||
DecodedJWT decoded = jwt.decodeWithoutVerification(token);
|
|
||||||
int userId = decoded.getClaim("userId").asInt();
|
|
||||||
if (userId == -1) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid token");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, new JsonObject()
|
|
||||||
.put("action", "getUserById")
|
|
||||||
.put("userId", userId), ar -> {
|
|
||||||
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonObject userJson = (JsonObject) ar.result().body();
|
|
||||||
UserEntity user = Constants.GSON.fromJson(userJson.encode(), UserEntity.class);
|
|
||||||
String newToken = jwt.generateToken(user.getUser_name(), user.getUser_id(), user.getGlobal_role(), false);
|
|
||||||
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, new JsonObject().put("token", newToken));
|
|
||||||
} else {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "User not found");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid token");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void getInfo(RoutingContext ctx) {
|
|
||||||
String authHeader = ctx.request().getHeader("Authorization");
|
|
||||||
|
|
||||||
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Unauthorized");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String token = authHeader.substring(7);
|
|
||||||
int userId = net.miarma.api.backlib.security.JWTManager.getInstance().getUserId(token);
|
|
||||||
|
|
||||||
if (userId <= 0) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid token");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "getInfo")
|
|
||||||
.put("userId", userId);
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void exists(RoutingContext ctx) {
|
|
||||||
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "userExists")
|
|
||||||
.put("userId", userId);
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getStatus(RoutingContext ctx) {
|
|
||||||
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "getStatus")
|
|
||||||
.put("userId", userId);
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getRole(RoutingContext ctx) {
|
|
||||||
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "getRole")
|
|
||||||
.put("userId", userId);
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getAvatar(RoutingContext ctx) {
|
|
||||||
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "getAvatar")
|
|
||||||
.put("userId", userId);
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateStatus(RoutingContext ctx) {
|
|
||||||
JsonObject body = ctx.body().asJsonObject();
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "updateStatus")
|
|
||||||
.put("userId", body.getInteger("userId"))
|
|
||||||
.put("status", body.getInteger("status"));
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null);
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateRole(RoutingContext ctx) {
|
|
||||||
JsonObject body = ctx.body().asJsonObject();
|
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
|
||||||
.put("action", "updateRole")
|
|
||||||
.put("userId", body.getInteger("userId"))
|
|
||||||
.put("role", body.getInteger("role"));
|
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.AUTH_EVENT_BUS, request, ar -> {
|
|
||||||
if (ar.succeeded()) {
|
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null);
|
|
||||||
} else {
|
|
||||||
EventBusUtil.handleReplyError(ctx, ar.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
package net.miarma.api.backlib.core.services;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
import io.vertx.sqlclient.Pool;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserGlobalStatus;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
|
||||||
import net.miarma.api.backlib.exceptions.AlreadyExistsException;
|
|
||||||
import net.miarma.api.backlib.exceptions.BadRequestException;
|
|
||||||
import net.miarma.api.backlib.exceptions.ForbiddenException;
|
|
||||||
import net.miarma.api.backlib.exceptions.NotFoundException;
|
|
||||||
import net.miarma.api.backlib.exceptions.UnauthorizedException;
|
|
||||||
import net.miarma.api.backlib.exceptions.ValidationException;
|
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
|
||||||
import net.miarma.api.backlib.security.JWTManager;
|
|
||||||
import net.miarma.api.backlib.security.PasswordHasher;
|
|
||||||
import net.miarma.api.backlib.core.dao.UserDAO;
|
|
||||||
import net.miarma.api.backlib.core.entities.UserEntity;
|
|
||||||
import net.miarma.api.backlib.core.validators.UserValidator;
|
|
||||||
|
|
||||||
public class UserService {
|
|
||||||
|
|
||||||
private final UserDAO userDAO;
|
|
||||||
private final UserValidator userValidator;
|
|
||||||
|
|
||||||
public UserService(Pool pool) {
|
|
||||||
this.userDAO = new UserDAO(pool);
|
|
||||||
this.userValidator = new UserValidator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* AUTHENTICATION */
|
|
||||||
|
|
||||||
public Future<JsonObject> login(String emailOrUsername, String plainPassword, boolean keepLoggedIn) {
|
|
||||||
return getByEmail(emailOrUsername).compose(user -> {
|
|
||||||
if (user == null) {
|
|
||||||
return getByUserName(emailOrUsername).compose(user2 -> {
|
|
||||||
if (user2 == null) {
|
|
||||||
return Future.succeededFuture(null);
|
|
||||||
}
|
|
||||||
return Future.succeededFuture(user2);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Future.succeededFuture(user);
|
|
||||||
}).compose(user -> {
|
|
||||||
|
|
||||||
if (user == null) {
|
|
||||||
return Future.failedFuture(new BadRequestException("Invalid credentials"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getGlobal_status() != Constants.CoreUserGlobalStatus.ACTIVE) {
|
|
||||||
return Future.failedFuture(new ForbiddenException("User is not active"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!PasswordHasher.verify(plainPassword, user.getPassword())) {
|
|
||||||
return Future.failedFuture(new BadRequestException("Invalid credentials"));
|
|
||||||
}
|
|
||||||
|
|
||||||
JWTManager jwtManager = JWTManager.getInstance();
|
|
||||||
String token = jwtManager.generateToken(user.getUser_name(), user.getUser_id(), user.getGlobal_role(), keepLoggedIn);
|
|
||||||
|
|
||||||
JsonObject response = new JsonObject()
|
|
||||||
.put("token", token)
|
|
||||||
.put("loggedUser", new JsonObject(user.encode()));
|
|
||||||
|
|
||||||
return Future.succeededFuture(response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<JsonObject> loginValidate(Integer userId, String password) {
|
|
||||||
return getById(userId).compose(user -> {
|
|
||||||
if (user == null) {
|
|
||||||
return Future.failedFuture(new NotFoundException("User not found"));
|
|
||||||
}
|
|
||||||
if (!PasswordHasher.verify(password, user.getPassword())) {
|
|
||||||
return Future.failedFuture(new BadRequestException("Invalid credentials"));
|
|
||||||
}
|
|
||||||
JsonObject response = new JsonObject()
|
|
||||||
.put("valid", true);
|
|
||||||
return Future.succeededFuture(response);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> register(UserEntity user) {
|
|
||||||
return getByEmail(user.getEmail()).compose(existing -> {
|
|
||||||
if (existing != null) {
|
|
||||||
return Future.failedFuture(new AlreadyExistsException("Email already exists"));
|
|
||||||
}
|
|
||||||
|
|
||||||
user.setPassword(PasswordHasher.hash(user.getPassword()));
|
|
||||||
user.setGlobal_role(CoreUserRole.USER);
|
|
||||||
user.setGlobal_status(CoreUserGlobalStatus.ACTIVE);
|
|
||||||
|
|
||||||
return userValidator.validate(user).compose(validation -> {
|
|
||||||
if (!validation.isValid()) {
|
|
||||||
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
|
|
||||||
}
|
|
||||||
return userDAO.insert(user);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> changePassword(int userId, String newPassword) {
|
|
||||||
return getById(userId).compose(user -> {
|
|
||||||
if (user == null) {
|
|
||||||
return Future.failedFuture(new NotFoundException("User not found"));
|
|
||||||
}
|
|
||||||
|
|
||||||
user.setPassword(PasswordHasher.hash(newPassword));
|
|
||||||
return userDAO.update(user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<Boolean> validateToken(String token) {
|
|
||||||
JWTManager jwtManager = JWTManager.getInstance();
|
|
||||||
return jwtManager.isValid(token) ?
|
|
||||||
Future.succeededFuture(true) :
|
|
||||||
Future.failedFuture(new UnauthorizedException("Invalid token"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* USERS OPERATIONS */
|
|
||||||
|
|
||||||
public Future<List<UserEntity>> getAll(QueryParams params) {
|
|
||||||
return userDAO.getAll(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> getById(Integer id) {
|
|
||||||
return userDAO.getById(id).compose(user -> {
|
|
||||||
if (user == null) {
|
|
||||||
return Future.failedFuture(new NotFoundException("User not found in the database"));
|
|
||||||
}
|
|
||||||
return Future.succeededFuture(user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> getByEmail(String email) {
|
|
||||||
return userDAO.getByEmail(email);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> getByUserName(String userName) {
|
|
||||||
return userDAO.getByUserName(userName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> updateRole(Integer userId, CoreUserRole role) {
|
|
||||||
return getById(userId).compose(user -> {
|
|
||||||
if (user == null) {
|
|
||||||
return Future.failedFuture(new NotFoundException("User not found in the database"));
|
|
||||||
}
|
|
||||||
user.setGlobal_role(role);
|
|
||||||
return userDAO.update(user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> updateStatus(Integer userId, CoreUserGlobalStatus status) {
|
|
||||||
return getById(userId).compose(user -> {
|
|
||||||
if (user == null) {
|
|
||||||
return Future.failedFuture(new NotFoundException("User not found in the database"));
|
|
||||||
}
|
|
||||||
user.setGlobal_status(status);
|
|
||||||
return userDAO.update(user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CRUD OPERATIONS */
|
|
||||||
|
|
||||||
public Future<UserEntity> create(UserEntity user) {
|
|
||||||
return userValidator.validate(user).compose(validation -> {
|
|
||||||
if (!validation.isValid()) {
|
|
||||||
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
|
|
||||||
}
|
|
||||||
return userDAO.insert(user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> update(UserEntity user) {
|
|
||||||
return userValidator.validate(user).compose(validation -> {
|
|
||||||
if (!validation.isValid()) {
|
|
||||||
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
|
|
||||||
}
|
|
||||||
if (user.getPassword() == null || user.getPassword().isEmpty()) {
|
|
||||||
user.setPassword(null);
|
|
||||||
}
|
|
||||||
return userDAO.update(user);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> upsert(UserEntity user) {
|
|
||||||
return userValidator.validate(user).compose(validation -> {
|
|
||||||
if (!validation.isValid()) {
|
|
||||||
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
|
|
||||||
}
|
|
||||||
if (user.getPassword() != null && !user.getPassword().isEmpty()) {
|
|
||||||
user.setPassword(PasswordHasher.hash(user.getPassword()));
|
|
||||||
}
|
|
||||||
return userDAO.upsert(user, "user_id", "email", "user_name");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<Boolean> delete(Integer id) {
|
|
||||||
return getById(id).compose(user -> {
|
|
||||||
if (user == null) {
|
|
||||||
return Future.failedFuture(new NotFoundException("User not found in the database"));
|
|
||||||
}
|
|
||||||
return userDAO.delete(id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
package net.miarma.api.backlib.core.validators;
|
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
|
||||||
import net.miarma.api.backlib.validation.ValidationResult;
|
|
||||||
import net.miarma.api.backlib.core.entities.FileEntity;
|
|
||||||
|
|
||||||
public class FileValidator {
|
|
||||||
|
|
||||||
public Future<ValidationResult> validate(FileEntity file, int size) {
|
|
||||||
ValidationResult result = new ValidationResult();
|
|
||||||
|
|
||||||
if (file == null) {
|
|
||||||
return Future.succeededFuture(result.addError("file", "El archivo no puede ser nulo"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getFile_name() == null || file.getFile_name().isBlank()) {
|
|
||||||
result.addError("file_name", "El nombre del archivo es obligatorio");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getMime_type() == null || file.getMime_type().isBlank()) {
|
|
||||||
result.addError("mime_type", "El tipo MIME es obligatorio");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getContext() == null) {
|
|
||||||
result.addError("context", "El contexto del archivo es obligatorio");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getUploaded_by() == null || file.getUploaded_by() <= 0) {
|
|
||||||
result.addError("uploaded_by", "El ID del usuario que subió el archivo es obligatorio y debe ser válido");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size <= 0) {
|
|
||||||
result.addError("size", "El archivo debe pesar más de 0 bytes");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getFile_name() != null && file.getFile_name().length() > 255) {
|
|
||||||
result.addError("file_name", "El nombre del archivo es demasiado largo");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size > 10485760) { // 10 MB limit
|
|
||||||
result.addError("size", "El archivo no puede pesar más de 10 MB");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Future.succeededFuture(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<ValidationResult> validate(FileEntity file) {
|
|
||||||
ValidationResult result = new ValidationResult();
|
|
||||||
|
|
||||||
if (file == null) {
|
|
||||||
return Future.succeededFuture(result.addError("file", "File cannot be null"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getFile_name() == null || file.getFile_name().isBlank()) {
|
|
||||||
result.addError("file_name", "File name is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getFile_path() == null || file.getFile_path().isBlank()) {
|
|
||||||
result.addError("file_path", "File path is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getMime_type() == null || file.getMime_type().isBlank()) {
|
|
||||||
result.addError("mime_type", "MIME type is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getContext() == null) {
|
|
||||||
result.addError("context", "File context is required");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getUploaded_by() == null || file.getUploaded_by() <= 0) {
|
|
||||||
result.addError("uploaded_by", "Uploader user ID is required and must be valid");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getFile_name() != null && file.getFile_name().length() > 255) {
|
|
||||||
result.addError("file_name", "File name is too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.getFile_path() != null && file.getFile_path().length() > 255) {
|
|
||||||
result.addError("file_path", "File path is too long");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Future.succeededFuture(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package net.miarma.api.backlib.core.validators;
|
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
|
||||||
import net.miarma.api.backlib.validation.ValidationResult;
|
|
||||||
import net.miarma.api.backlib.core.entities.UserEntity;
|
|
||||||
|
|
||||||
public class UserValidator {
|
|
||||||
|
|
||||||
public Future<ValidationResult> validate(UserEntity user) {
|
|
||||||
ValidationResult result = new ValidationResult();
|
|
||||||
|
|
||||||
if (user == null) {
|
|
||||||
return Future.succeededFuture(result.addError("user", "El usuario no puede ser nulo"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getUser_name() == null || user.getUser_name().isBlank()) {
|
|
||||||
result.addError("user_name", "El nombre de usuario es obligatorio");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getDisplay_name() == null || user.getDisplay_name().isBlank()) {
|
|
||||||
result.addError("display_name", "El nombre para mostrar es obligatorio");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getEmail() != null && !user.getEmail().isBlank()) {
|
|
||||||
if (!user.getEmail().matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
|
|
||||||
result.addError("email", "El correo electrónico no es válido");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getPassword() == null || user.getPassword().isBlank()) {
|
|
||||||
result.addError("password", "La contraseña es obligatoria");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getGlobal_status() == null) {
|
|
||||||
result.addError("global_status", "El estado global del usuario es obligatorio");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.getGlobal_role() == null) {
|
|
||||||
result.addError("role", "El rol del usuario es obligatorio");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Future.succeededFuture(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +1,45 @@
|
|||||||
package net.miarma.api.backlib.db;
|
package net.miarma.api.backlib.db;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.UUID;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import io.vertx.core.buffer.Buffer;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.sqlclient.Row;
|
import io.vertx.sqlclient.Row;
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.ValuableEnum;
|
|
||||||
import net.miarma.api.backlib.annotations.APIDontReturn;
|
import net.miarma.api.backlib.annotations.APIDontReturn;
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
|
import net.miarma.api.backlib.util.BufferUtil;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clase base para todas las entidades persistentes del sistema.
|
|
||||||
* <p>
|
|
||||||
* Proporciona utilidades para:
|
|
||||||
* <ul>
|
|
||||||
* <li>Construir una entidad a partir de una fila de base de datos ({@link Row})</li>
|
|
||||||
* <li>Serializar una entidad a {@link JsonObject}</li>
|
|
||||||
* <li>Generar una representación en texto</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* Los campos se mapean por reflexión, lo que permite extender fácilmente las entidades
|
|
||||||
* sin necesidad de escribir lógica de parsing repetitiva.
|
|
||||||
*
|
|
||||||
* @author José Manuel Amador Gallardo
|
|
||||||
*/
|
|
||||||
public abstract class AbstractEntity {
|
public abstract class AbstractEntity {
|
||||||
|
private final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor por defecto. Requerido para instanciación sin datos.
|
|
||||||
*/
|
|
||||||
public AbstractEntity() {}
|
public AbstractEntity() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor que inicializa los campos de la entidad a partir de una fila de base de datos.
|
|
||||||
*
|
|
||||||
* @param row Fila SQL proporcionada por Vert.x.
|
|
||||||
*/
|
|
||||||
public AbstractEntity(Row row) {
|
public AbstractEntity(Row row) {
|
||||||
populateFromRow(row);
|
populateFromRow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String getColumnName(Field field) {
|
||||||
* Rellena los campos del objeto usando reflexión a partir de una {@link Row} de Vert.x.
|
if (field.isAnnotationPresent(SerializedName.class)) {
|
||||||
* Se soportan tipos básicos (String, int, boolean, etc.), enums con método estático {@code fromInt(int)},
|
return field.getAnnotation(SerializedName.class).value();
|
||||||
* y {@link java.math.BigDecimal} (a través del tipo {@code Numeric} de Vert.x).
|
}
|
||||||
* <p>
|
return field.getName();
|
||||||
* Si un tipo no está soportado, se registra un error en el log y se ignora ese campo.
|
}
|
||||||
*
|
|
||||||
* @param row Fila de datos de la que extraer los valores.
|
|
||||||
*/
|
|
||||||
private void populateFromRow(Row row) {
|
private void populateFromRow(Row row) {
|
||||||
Field[] fields = this.getClass().getDeclaredFields();
|
Field[] fields = this.getClass().getDeclaredFields();
|
||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
try {
|
try {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
Class<?> type = field.getType();
|
Class<?> type = field.getType();
|
||||||
String name = field.getName();
|
String columnName = getColumnName(field);
|
||||||
|
|
||||||
Object value;
|
Object value;
|
||||||
if (type.isEnum()) {
|
if (type.isEnum()) {
|
||||||
Integer intValue = row.getInteger(name);
|
Integer intValue = row.getInteger(columnName);
|
||||||
if (intValue != null) {
|
if (intValue != null) {
|
||||||
try {
|
try {
|
||||||
var method = type.getMethod("fromInt", int.class);
|
var method = type.getMethod("fromInt", int.class);
|
||||||
@@ -71,42 +52,43 @@ public abstract class AbstractEntity {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value = switch (type.getSimpleName()) {
|
value = switch (type.getSimpleName()) {
|
||||||
case "Integer", "int" -> row.getInteger(name);
|
case "Integer", "int" -> row.getInteger(columnName);
|
||||||
case "String" -> row.getString(name);
|
case "String" -> row.getString(columnName);
|
||||||
case "double", "Double" -> row.getDouble(name);
|
case "double", "Double" -> row.getDouble(columnName);
|
||||||
case "long", "Long" -> row.getLong(name);
|
case "long", "Long" -> row.getLong(columnName);
|
||||||
case "boolean", "Boolean" -> row.getBoolean(name);
|
case "boolean", "Boolean" -> row.getBoolean(columnName);
|
||||||
case "LocalDateTime" -> row.getLocalDateTime(name);
|
case "LocalDateTime" -> row.getLocalDateTime(columnName);
|
||||||
case "BigDecimal" -> {
|
case "UUID" -> {
|
||||||
try {
|
Object raw = row.getValue(columnName);
|
||||||
var numeric = row.get(io.vertx.sqlclient.data.Numeric.class, row.getColumnIndex(name));
|
if (raw instanceof UUID) yield raw;
|
||||||
yield numeric != null ? numeric.bigDecimalValue() : null;
|
if (raw instanceof String s) yield UUID.fromString(s);
|
||||||
} catch (Exception e) {
|
if (raw instanceof Buffer b) {
|
||||||
|
yield BufferUtil.uuidFromBuffer(b);
|
||||||
|
}
|
||||||
yield null;
|
yield null;
|
||||||
}
|
}
|
||||||
|
case "BigDecimal" -> {
|
||||||
|
try {
|
||||||
|
var numeric = row.get(io.vertx.sqlclient.data.Numeric.class, row.getColumnIndex(columnName));
|
||||||
|
yield numeric != null ? numeric.bigDecimalValue() : null;
|
||||||
|
} catch (Exception e) { yield null; }
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
Constants.LOGGER.error("Type not supported yet: {} for field {}", type.getName(), name);
|
LOGGER.error("Type not supported yet: {} for field {}", type.getName(), field.getName());
|
||||||
yield null;
|
yield null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value != null) {
|
||||||
field.set(this, value);
|
field.set(this, value);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Constants.LOGGER.error("Error populating field {}: {}", field.getName(), e.getMessage());
|
LOGGER.error("Error populating field {}: {}", field.getName(), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Codifica esta entidad como un objeto JSON, omitiendo los campos anotados con {@link APIDontReturn}.
|
|
||||||
*
|
|
||||||
* <p>Si un campo implementa {@link ValuableEnum}, se usará su valor en lugar del nombre del enum.</p>
|
|
||||||
*
|
|
||||||
* @return Representación JSON de esta entidad.
|
|
||||||
*/
|
|
||||||
public String encode() {
|
public String encode() {
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
Class<?> clazz = this.getClass();
|
Class<?> clazz = this.getClass();
|
||||||
@@ -114,33 +96,25 @@ public abstract class AbstractEntity {
|
|||||||
while (clazz != null) {
|
while (clazz != null) {
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
if (field.isAnnotationPresent(APIDontReturn.class)) continue;
|
if (field.isAnnotationPresent(APIDontReturn.class)) continue;
|
||||||
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
Object value = field.get(this);
|
Object value = field.get(this);
|
||||||
|
if (value instanceof IValuableEnum ve) {
|
||||||
if (value instanceof ValuableEnum ve) {
|
|
||||||
json.put(field.getName(), ve.getValue());
|
json.put(field.getName(), ve.getValue());
|
||||||
|
} else if (value instanceof UUID u) {
|
||||||
|
json.put(field.getName(), u.toString());
|
||||||
} else {
|
} else {
|
||||||
json.put(field.getName(), value);
|
json.put(field.getName(), value);
|
||||||
}
|
}
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
Constants.LOGGER.error("Error accessing field {}: {}", field.getName(), e.getMessage());
|
LOGGER.error("Error accessing field {}: {}", field.getName(), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clazz = clazz.getSuperclass();
|
clazz = clazz.getSuperclass();
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.encode();
|
return json.encode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Devuelve una representación en texto de la entidad, mostrando todos los campos y sus valores.
|
|
||||||
*
|
|
||||||
* <p>Útil para logs y debugging.</p>
|
|
||||||
*
|
|
||||||
* @return Cadena de texto con el nombre de la clase y todos los campos.
|
|
||||||
*/
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(this.getClass().getSimpleName()).append(" [ ");
|
sb.append(this.getClass().getSimpleName()).append(" [ ");
|
||||||
@@ -148,13 +122,12 @@ public abstract class AbstractEntity {
|
|||||||
for (Field field : fields) {
|
for (Field field : fields) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
sb.append(field.getName()).append("= ").append(field.get(this)).append(", ");
|
sb.append(field.getName()).append("=").append(field.get(this)).append(", ");
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
Constants.LOGGER.error("Error stringing field {}: {}", field.getName(), e.getMessage());
|
LOGGER.error("Error stringing field {}: {}", field.getName(), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.append("]");
|
sb.append("]");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,18 @@
|
|||||||
package net.miarma.api.backlib.db;
|
package net.miarma.api.backlib.db;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import io.vertx.sqlclient.Row;
|
import io.vertx.sqlclient.Row;
|
||||||
import io.vertx.sqlclient.RowSet;
|
import io.vertx.sqlclient.RowSet;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gestor centralizado de acceso a la base de datos utilizando Vert.x SQL Client.
|
* Gestor centralizado de acceso a la base de datos utilizando Vert.x SQL Client.
|
||||||
@@ -23,6 +25,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class DatabaseManager {
|
public class DatabaseManager {
|
||||||
|
|
||||||
|
private final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
private static DatabaseManager instance;
|
private static DatabaseManager instance;
|
||||||
private final Pool pool;
|
private final Pool pool;
|
||||||
|
|
||||||
@@ -86,7 +89,7 @@ public class DatabaseManager {
|
|||||||
results.add(constructor.newInstance(row));
|
results.add(constructor.newInstance(row));
|
||||||
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException
|
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException
|
||||||
| InvocationTargetException e) {
|
| InvocationTargetException e) {
|
||||||
Constants.LOGGER.error("Error instantiating class: {}", e.getMessage());
|
LOGGER.error("Error instantiating class: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
@@ -116,7 +119,7 @@ public class DatabaseManager {
|
|||||||
Constructor<T> constructor = clazz.getConstructor(Row.class);
|
Constructor<T> constructor = clazz.getConstructor(Row.class);
|
||||||
return constructor.newInstance(row);
|
return constructor.newInstance(row);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Constants.LOGGER.error("Error instantiating class: {}", e.getMessage());
|
LOGGER.error("Error instantiating class: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null; // Si no hay filas
|
return null; // Si no hay filas
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import io.vertx.core.Vertx;
|
|||||||
import io.vertx.mysqlclient.MySQLConnectOptions;
|
import io.vertx.mysqlclient.MySQLConnectOptions;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import io.vertx.sqlclient.PoolOptions;
|
import io.vertx.sqlclient.PoolOptions;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factoría de {@link Pool} para conexiones MySQL usando Vert.x.
|
* Factoría de {@link Pool} para conexiones MySQL usando Vert.x.
|
||||||
|
|||||||
@@ -1,64 +1,42 @@
|
|||||||
package net.miarma.api.backlib.db;
|
package net.miarma.api.backlib.db;
|
||||||
|
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.annotations.Table;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
import org.slf4j.Logger;
|
||||||
* Clase utilitaria para construir queries SQL dinámicamente mediante reflexión,
|
import com.google.gson.annotations.SerializedName;
|
||||||
* usando entidades anotadas con {@link Table}.
|
import net.miarma.api.backlib.annotations.Table;
|
||||||
* <p>
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
* Soporta operaciones SELECT, INSERT, UPDATE (con y sin valores nulos), y UPSERT.
|
|
||||||
* También permite aplicar filtros desde un mapa o directamente desde un objeto.
|
|
||||||
* <p>
|
|
||||||
* ¡Ojo! No ejecuta la query, solo la construye.
|
|
||||||
*
|
|
||||||
* @author José Manuel Amador Gallardo
|
|
||||||
*/
|
|
||||||
public class QueryBuilder {
|
public class QueryBuilder {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
private final StringBuilder query;
|
private final StringBuilder query;
|
||||||
private String sort;
|
private String orderByClause;
|
||||||
private String order;
|
private String limitClause;
|
||||||
private String limit;
|
private String offsetClause;
|
||||||
private Class<?> entityClass;
|
private Class<?> entityClass;
|
||||||
|
|
||||||
public QueryBuilder() {
|
public QueryBuilder() {
|
||||||
this.query = new StringBuilder();
|
this.query = new StringBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtiene el nombre de la tabla desde la anotación @Table de la clase dada.
|
|
||||||
*/
|
|
||||||
private static <T> String getTableName(Class<T> clazz) {
|
private static <T> String getTableName(Class<T> clazz) {
|
||||||
if (clazz == null) {
|
if (clazz == null) throw new IllegalArgumentException("Class cannot be null");
|
||||||
throw new IllegalArgumentException("Class cannot be null");
|
if (!clazz.isAnnotationPresent(Table.class)) throw new IllegalArgumentException("Class does not have @Table annotation");
|
||||||
|
return clazz.getAnnotation(Table.class).value();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clazz.isAnnotationPresent(Table.class)) {
|
private static String getColumnName(Field field) {
|
||||||
Table annotation = clazz.getAnnotation(Table.class);
|
SerializedName annotation = field.getAnnotation(SerializedName.class);
|
||||||
return annotation.value();
|
return annotation != null ? annotation.value() : field.getName();
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Class does not have @Table annotation");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Devuelve la consulta SQL construida hasta el momento.
|
|
||||||
*/
|
|
||||||
public String getQuery() {
|
|
||||||
return query.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extrae el valor de un campo, manejando enums y tipos especiales.
|
|
||||||
* Si es un Enum y tiene getValue(), lo usa; si no, devuelve el name().
|
|
||||||
* Si es un LocalDateTime, lo convierte a String en formato SQL.
|
|
||||||
*/
|
|
||||||
private static Object extractValue(Object fieldValue) {
|
private static Object extractValue(Object fieldValue) {
|
||||||
|
if (fieldValue == null) return null;
|
||||||
if (fieldValue instanceof Enum<?>) {
|
if (fieldValue instanceof Enum<?>) {
|
||||||
try {
|
try {
|
||||||
var method = fieldValue.getClass().getMethod("getValue");
|
var method = fieldValue.getClass().getMethod("getValue");
|
||||||
@@ -67,199 +45,137 @@ public class QueryBuilder {
|
|||||||
return ((Enum<?>) fieldValue).name();
|
return ((Enum<?>) fieldValue).name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldValue instanceof LocalDateTime ldt) {
|
if (fieldValue instanceof LocalDateTime ldt) {
|
||||||
return ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
return ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return fieldValue;
|
return fieldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String formatValue(Object value) {
|
||||||
* Escapa los caracteres especiales en una cadena para evitar inyecciones SQL.
|
if (value == null) return "NULL";
|
||||||
* @param value the string value to escape
|
if (value instanceof UUID uuid) {
|
||||||
* @return the escaped string
|
return "UNHEX(REPLACE('" + uuid.toString() + "','-',''))";
|
||||||
*/
|
}
|
||||||
|
if (value instanceof String || value instanceof LocalDateTime) {
|
||||||
|
return "'" + escapeSql(value.toString()) + "'";
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private static String escapeSql(String value) {
|
private static String escapeSql(String value) {
|
||||||
return value.replace("'", "''");
|
return value.replace("'", "''");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construye una consulta SELECT para la clase dada, con columnas opcionales.
|
* @param clazz La clase de la entidad a seleccionar
|
||||||
* @param clazz the entity class to query
|
* @param columns Columnas a seleccionar, si no se pasan selecciona "*"
|
||||||
* @param columns optional columns to select; if empty, selects all columns
|
|
||||||
* @return the current QueryBuilder instance
|
|
||||||
* @param <T> the type of the entity class
|
|
||||||
*/
|
*/
|
||||||
public static <T> QueryBuilder select(Class<T> clazz, String... columns) {
|
public static <T> QueryBuilder select(Class<T> clazz, String... columns) {
|
||||||
if (clazz == null) {
|
|
||||||
throw new IllegalArgumentException("Class cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder qb = new QueryBuilder();
|
QueryBuilder qb = new QueryBuilder();
|
||||||
qb.entityClass = clazz;
|
qb.entityClass = clazz;
|
||||||
String tableName = getTableName(clazz);
|
|
||||||
|
|
||||||
qb.query.append("SELECT ");
|
qb.query.append("SELECT ");
|
||||||
|
if (columns.length == 0) qb.query.append("* ");
|
||||||
if (columns.length == 0) {
|
else qb.query.append(String.join(", ", columns)).append(" ");
|
||||||
qb.query.append("* ");
|
qb.query.append("FROM ").append(getTableName(clazz)).append(" ");
|
||||||
} else {
|
|
||||||
StringJoiner joiner = new StringJoiner(", ");
|
|
||||||
for (String column : columns) {
|
|
||||||
if (column != null) {
|
|
||||||
joiner.add(column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
qb.query.append(joiner).append(" ");
|
|
||||||
}
|
|
||||||
|
|
||||||
qb.query.append("FROM ").append(tableName).append(" ");
|
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Añade una cláusula WHERE a la consulta actual, filtrando por los campos del mapa.
|
* @param filters Mapa clave = valor para el WHERE. Detecta UUID y Strings tipo IN
|
||||||
* Los valores pueden ser números o cadenas, y se manejan adecuadamente.
|
|
||||||
*
|
|
||||||
* @param filters un mapa de filtros donde la clave es el nombre del campo y el valor es el valor a filtrar
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
*/
|
*/
|
||||||
public QueryBuilder where(Map<String, String> filters) {
|
public QueryBuilder where(Map<String, Object> filters) {
|
||||||
if (filters == null || filters.isEmpty()) {
|
if (filters == null || filters.isEmpty() || entityClass == null) return this;
|
||||||
|
|
||||||
|
Map<String, String> javaToSql = new HashMap<>();
|
||||||
|
Map<String, String> sqlToSql = new HashMap<>();
|
||||||
|
for (Field f : entityClass.getDeclaredFields()) {
|
||||||
|
String sqlCol = getColumnName(f);
|
||||||
|
javaToSql.put(f.getName(), sqlCol);
|
||||||
|
sqlToSql.put(sqlCol, sqlCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> conditions = new ArrayList<>();
|
||||||
|
for (Map.Entry<String, Object> entry : filters.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
String sqlCol = javaToSql.getOrDefault(key, sqlToSql.get(key));
|
||||||
|
if (sqlCol == null) {
|
||||||
|
LOGGER.warn("[QueryBuilder] Ignorando campo invalido en WHERE: {}", key);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Object val = entry.getValue();
|
||||||
|
if (val == null) continue;
|
||||||
|
if (val instanceof String s && s.startsWith("(") && s.endsWith(")")) conditions.add(sqlCol + " IN " + s);
|
||||||
|
else conditions.add(sqlCol + " = " + formatValue(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!conditions.isEmpty()) {
|
||||||
|
String prefix = query.toString().contains("WHERE") ? "AND " : "WHERE ";
|
||||||
|
query.append(prefix).append(String.join(" AND ", conditions)).append(" ");
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> validFields = entityClass != null
|
/**
|
||||||
? Arrays.stream(entityClass.getDeclaredFields()).map(Field::getName).collect(Collectors.toSet())
|
* @param object Objeto con campos para WHERE. Soporta UUID y LocalDateTime
|
||||||
: Collections.emptySet();
|
*/
|
||||||
|
public <T> QueryBuilder where(T object) {
|
||||||
|
if (object == null) throw new IllegalArgumentException("Object cannot be null");
|
||||||
|
if (entityClass == null) return this;
|
||||||
|
|
||||||
|
Set<String> validColumns = Arrays.stream(entityClass.getDeclaredFields())
|
||||||
|
.map(QueryBuilder::getColumnName)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
List<String> conditions = new ArrayList<>();
|
List<String> conditions = new ArrayList<>();
|
||||||
|
for (Field field : object.getClass().getDeclaredFields()) {
|
||||||
for (Map.Entry<String, String> entry : filters.entrySet()) {
|
field.setAccessible(true);
|
||||||
String key = entry.getKey();
|
try {
|
||||||
String value = entry.getValue();
|
Object value = field.get(object);
|
||||||
|
if (value != null) {
|
||||||
if (!validFields.contains(key)) {
|
String col = getColumnName(field);
|
||||||
Constants.LOGGER.warn("[QueryBuilder] Ignorando campo invalido en WHERE: {}", key);
|
if (!validColumns.contains(col)) continue;
|
||||||
continue;
|
Object extracted = extractValue(value);
|
||||||
|
conditions.add(col + " = " + formatValue(extracted));
|
||||||
}
|
}
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
if (value.startsWith("(") && value.endsWith(")")) {
|
LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
||||||
conditions.add(key + " IN " + value);
|
|
||||||
} else if (value.matches("-?\\d+(\\.\\d+)?")) {
|
|
||||||
conditions.add(key + " = " + value);
|
|
||||||
} else {
|
|
||||||
conditions.add(key + " = '" + value + "'");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!conditions.isEmpty()) {
|
if (!conditions.isEmpty()) {
|
||||||
query.append("WHERE ").append(String.join(" AND ", conditions)).append(" ");
|
String prefix = query.toString().contains("WHERE") ? "AND " : "WHERE ";
|
||||||
|
query.append(prefix).append(String.join(" AND ", conditions)).append(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Añade una cláusula WHERE a la consulta actual, filtrando por los campos del objeto.
|
|
||||||
* Los valores se extraen mediante reflexión y se manejan adecuadamente.
|
|
||||||
*
|
|
||||||
* @param object el objeto del cual se extraerán los campos para filtrar
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
*/
|
|
||||||
public <T> QueryBuilder where(T object) {
|
|
||||||
if (object == null) {
|
|
||||||
throw new IllegalArgumentException("Object cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> validFields = entityClass != null
|
|
||||||
? Arrays.stream(entityClass.getDeclaredFields()).map(Field::getName).collect(Collectors.toSet())
|
|
||||||
: Collections.emptySet();
|
|
||||||
|
|
||||||
this.query.append("WHERE ");
|
|
||||||
StringJoiner joiner = new StringJoiner(" AND ");
|
|
||||||
for (Field field : object.getClass().getDeclaredFields()) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
try {
|
|
||||||
Object fieldValue = field.get(object);
|
|
||||||
if (fieldValue != null) {
|
|
||||||
String key = field.getName();
|
|
||||||
if (!validFields.contains(key)) {
|
|
||||||
Constants.LOGGER.warn("[QueryBuilder] Ignorando campo invalido en WHERE: {}", key);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Object value = extractValue(fieldValue);
|
|
||||||
if (value instanceof String || value instanceof LocalDateTime) {
|
|
||||||
joiner.add(key + " = '" + value + "'");
|
|
||||||
} else {
|
|
||||||
joiner.add(key + " = " + value.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
|
||||||
Constants.LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.query.append(joiner).append(" ");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construye una consulta INSERT para el objeto dado, insertando todos sus campos.
|
|
||||||
* Los valores se extraen mediante reflexión y se manejan adecuadamente.
|
|
||||||
*
|
|
||||||
* @param object el objeto a insertar
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
* @param <T> el tipo del objeto a insertar
|
|
||||||
*/
|
|
||||||
public static <T> QueryBuilder insert(T object) {
|
public static <T> QueryBuilder insert(T object) {
|
||||||
if (object == null) {
|
if (object == null) throw new IllegalArgumentException("Object cannot be null");
|
||||||
throw new IllegalArgumentException("Object cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder qb = new QueryBuilder();
|
QueryBuilder qb = new QueryBuilder();
|
||||||
String table = getTableName(object.getClass());
|
String table = getTableName(object.getClass());
|
||||||
qb.query.append("INSERT INTO ").append(table).append(" ");
|
qb.query.append("INSERT INTO ").append(table).append(" ");
|
||||||
qb.query.append("(");
|
|
||||||
StringJoiner columns = new StringJoiner(", ");
|
StringJoiner cols = new StringJoiner(", ");
|
||||||
StringJoiner values = new StringJoiner(", ");
|
StringJoiner vals = new StringJoiner(", ");
|
||||||
|
|
||||||
for (Field field : object.getClass().getDeclaredFields()) {
|
for (Field field : object.getClass().getDeclaredFields()) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
columns.add(field.getName());
|
cols.add(getColumnName(field));
|
||||||
Object fieldValue = field.get(object);
|
Object value = extractValue(field.get(object));
|
||||||
if (fieldValue != null) {
|
vals.add(qb.formatValue(value));
|
||||||
Object value = extractValue(fieldValue);
|
} catch (IllegalAccessException e) {
|
||||||
if (value instanceof String || value instanceof LocalDateTime) {
|
LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
||||||
values.add("'" + escapeSql((String) value) + "'");
|
|
||||||
} else {
|
|
||||||
values.add(value.toString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
values.add("NULL");
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException | IllegalAccessException e) {
|
|
||||||
Constants.LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qb.query.append(columns).append(") ");
|
|
||||||
qb.query.append("VALUES (").append(values).append(") RETURNING * ");
|
qb.query.append("(").append(cols).append(") VALUES (").append(vals).append(") RETURNING * ");
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static <T> QueryBuilder buildUpdate(T object, boolean includeNulls) {
|
||||||
* Construye una consulta UPDATE para el objeto dado, actualizando todos sus campos.
|
if (object == null) throw new IllegalArgumentException("Object cannot be null");
|
||||||
* Los valores se extraen mediante reflexión y se manejan adecuadamente.
|
|
||||||
* Requiere que el objeto tenga un campo ID (terminado en _id) para la cláusula WHERE.
|
|
||||||
*
|
|
||||||
* @param object el objeto a actualizar
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
* @param <T> el tipo del objeto a actualizar
|
|
||||||
*/
|
|
||||||
public static <T> QueryBuilder update(T object) {
|
|
||||||
if (object == null) {
|
|
||||||
throw new IllegalArgumentException("Object cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder qb = new QueryBuilder();
|
QueryBuilder qb = new QueryBuilder();
|
||||||
String table = getTableName(object.getClass());
|
String table = getTableName(object.getClass());
|
||||||
@@ -267,103 +183,36 @@ public class QueryBuilder {
|
|||||||
|
|
||||||
StringJoiner setJoiner = new StringJoiner(", ");
|
StringJoiner setJoiner = new StringJoiner(", ");
|
||||||
StringJoiner whereJoiner = new StringJoiner(" AND ");
|
StringJoiner whereJoiner = new StringJoiner(" AND ");
|
||||||
|
|
||||||
Field idField = null;
|
Field idField = null;
|
||||||
|
|
||||||
for (Field field : object.getClass().getDeclaredFields()) {
|
for (Field field : object.getClass().getDeclaredFields()) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
Object fieldValue = field.get(object);
|
String col = getColumnName(field);
|
||||||
if (fieldValue == null) continue;
|
Object value = extractValue(field.get(object));
|
||||||
|
if (col.endsWith("_id")) {
|
||||||
String fieldName = field.getName();
|
|
||||||
Object value = extractValue(fieldValue);
|
|
||||||
|
|
||||||
if (fieldName.endsWith("_id")) {
|
|
||||||
idField = field;
|
idField = field;
|
||||||
whereJoiner.add(fieldName + " = " + (value instanceof String
|
if (value != null) whereJoiner.add(col + " = " + qb.formatValue(value));
|
||||||
|| value instanceof LocalDateTime ? "'" + value + "'" : value));
|
else throw new IllegalArgumentException("ID field cannot be null");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (value != null) setJoiner.add(col + " = " + qb.formatValue(value));
|
||||||
setJoiner.add(fieldName + " = " + (value instanceof String
|
else if (includeNulls) setJoiner.add(col + " = NULL");
|
||||||
|| value instanceof LocalDateTime ? "'" + value + "'" : value));
|
} catch (IllegalAccessException e) {
|
||||||
} catch (Exception e) {
|
LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
||||||
Constants.LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idField == null) {
|
if (idField == null) throw new IllegalArgumentException("No ID field (ending with _id) found for WHERE clause");
|
||||||
throw new IllegalArgumentException("No ID field (ending with _id) found for WHERE clause");
|
|
||||||
}
|
|
||||||
|
|
||||||
qb.query.append(setJoiner).append(" WHERE ").append(whereJoiner);
|
qb.query.append(setJoiner).append(" WHERE ").append(whereJoiner).append(" ");
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static <T> QueryBuilder update(T object) { return buildUpdate(object, false); }
|
||||||
* Construye una consulta UPDATE que establece los campos a NULL si son nulos.
|
|
||||||
* Requiere que el objeto tenga un campo ID (terminado en _id) para la cláusula WHERE.
|
|
||||||
*
|
|
||||||
* @param object el objeto a actualizar
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
* @param <T> el tipo del objeto a actualizar
|
|
||||||
*/
|
|
||||||
public static <T> QueryBuilder updateWithNulls(T object) {
|
|
||||||
if (object == null) {
|
|
||||||
throw new IllegalArgumentException("Object cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryBuilder qb = new QueryBuilder();
|
public static <T> QueryBuilder updateWithNulls(T object) { return buildUpdate(object, true); }
|
||||||
String table = getTableName(object.getClass());
|
|
||||||
qb.query.append("UPDATE ").append(table).append(" SET ");
|
|
||||||
|
|
||||||
StringJoiner setJoiner = new StringJoiner(", ");
|
|
||||||
StringJoiner whereJoiner = new StringJoiner(" AND ");
|
|
||||||
|
|
||||||
Field idField = null;
|
|
||||||
|
|
||||||
for (Field field : object.getClass().getDeclaredFields()) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
try {
|
|
||||||
String fieldName = field.getName();
|
|
||||||
Object fieldValue = field.get(object);
|
|
||||||
|
|
||||||
if (fieldName.endsWith("_id")) {
|
|
||||||
idField = field;
|
|
||||||
Object value = extractValue(fieldValue);
|
|
||||||
whereJoiner.add(fieldName + " = " + (value instanceof String || value instanceof LocalDateTime ? "'" + value + "'" : value));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldValue == null) {
|
|
||||||
setJoiner.add(fieldName + " = NULL");
|
|
||||||
} else {
|
|
||||||
Object value = extractValue(fieldValue);
|
|
||||||
setJoiner.add(fieldName + " = " + (value instanceof String || value instanceof LocalDateTime ? "'" + value + "'" : value));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Constants.LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idField == null) {
|
|
||||||
throw new IllegalArgumentException("No ID field (ending with _id) found for WHERE clause");
|
|
||||||
}
|
|
||||||
|
|
||||||
qb.query.append(setJoiner).append(" WHERE ").append(whereJoiner);
|
|
||||||
return qb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construye una consulta UPSERT (INSERT o UPDATE) para el objeto dado.
|
|
||||||
* Si hay claves de conflicto, se actualizan los campos excepto las claves duplicadas.
|
|
||||||
*
|
|
||||||
* @param object el objeto a insertar o actualizar
|
|
||||||
* @param conflictKeys las claves que causan conflictos y no deben actualizarse
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
* @param <T> el tipo del objeto a insertar o actualizar
|
|
||||||
*/
|
|
||||||
public static <T> QueryBuilder upsert(T object, String... conflictKeys) {
|
public static <T> QueryBuilder upsert(T object, String... conflictKeys) {
|
||||||
if (object == null) throw new IllegalArgumentException("Object cannot be null");
|
if (object == null) throw new IllegalArgumentException("Object cannot be null");
|
||||||
|
|
||||||
@@ -371,146 +220,75 @@ public class QueryBuilder {
|
|||||||
String table = getTableName(object.getClass());
|
String table = getTableName(object.getClass());
|
||||||
qb.query.append("INSERT INTO ").append(table).append(" ");
|
qb.query.append("INSERT INTO ").append(table).append(" ");
|
||||||
|
|
||||||
StringJoiner columns = new StringJoiner(", ");
|
StringJoiner cols = new StringJoiner(", ");
|
||||||
StringJoiner values = new StringJoiner(", ");
|
StringJoiner vals = new StringJoiner(", ");
|
||||||
Map<String, String> updates = new HashMap<>();
|
Map<String, String> updates = new HashMap<>();
|
||||||
|
|
||||||
for (Field field : object.getClass().getDeclaredFields()) {
|
for (Field field : object.getClass().getDeclaredFields()) {
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
try {
|
try {
|
||||||
Object fieldValue = field.get(object);
|
String col = getColumnName(field);
|
||||||
String columnName = field.getName();
|
Object value = extractValue(field.get(object));
|
||||||
columns.add(columnName);
|
String formatted = qb.formatValue(value);
|
||||||
|
cols.add(col);
|
||||||
Object value = extractValue(fieldValue);
|
vals.add(formatted);
|
||||||
String valueStr = value == null ? "NULL"
|
if (!Arrays.asList(conflictKeys).contains(col)) updates.put(col, formatted);
|
||||||
: (value instanceof String || value instanceof LocalDateTime ? "'" + value + "'" : value.toString());
|
} catch (IllegalAccessException e) {
|
||||||
values.add(valueStr);
|
LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
||||||
|
|
||||||
// no actualizamos la clave duplicada
|
|
||||||
boolean isConflictKey = Arrays.asList(conflictKeys).contains(columnName);
|
|
||||||
if (!isConflictKey) {
|
|
||||||
updates.put(columnName, valueStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
Constants.LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qb.query.append("(").append(columns).append(") VALUES (").append(values).append(")");
|
qb.query.append("(").append(cols).append(") VALUES (").append(vals).append(")");
|
||||||
|
if (!updates.isEmpty() && conflictKeys.length > 0) {
|
||||||
if (conflictKeys.length > 0 && !updates.isEmpty()) {
|
|
||||||
qb.query.append(" ON DUPLICATE KEY UPDATE ");
|
qb.query.append(" ON DUPLICATE KEY UPDATE ");
|
||||||
StringJoiner updateSet = new StringJoiner(", ");
|
qb.query.append(updates.entrySet().stream()
|
||||||
updates.forEach((k, v) -> updateSet.add(k + " = " + v));
|
.map(e -> e.getKey() + " = " + e.getValue())
|
||||||
qb.query.append(updateSet);
|
.collect(Collectors.joining(", ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construye una consulta DELETE para el objeto dado, eliminando registros que coincidan con sus campos.
|
|
||||||
* Los valores se extraen mediante reflexión y se manejan adecuadamente.
|
|
||||||
*
|
|
||||||
* @param object el objeto a eliminar
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
* @param <T> el tipo del objeto a eliminar
|
|
||||||
*/
|
|
||||||
public static <T> QueryBuilder delete(T object) {
|
public static <T> QueryBuilder delete(T object) {
|
||||||
if (object == null) throw new IllegalArgumentException("Object cannot be null");
|
if (object == null) throw new IllegalArgumentException("Object cannot be null");
|
||||||
|
|
||||||
QueryBuilder qb = new QueryBuilder();
|
QueryBuilder qb = new QueryBuilder();
|
||||||
String table = getTableName(object.getClass());
|
qb.entityClass = object.getClass();
|
||||||
qb.query.append("DELETE FROM ").append(table).append(" WHERE ");
|
String table = getTableName(qb.entityClass);
|
||||||
|
qb.query.append("DELETE FROM ").append(table).append(" ");
|
||||||
StringJoiner joiner = new StringJoiner(" AND ");
|
return qb.where(object);
|
||||||
for (Field field : object.getClass().getDeclaredFields()) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
try {
|
|
||||||
Object fieldValue = field.get(object);
|
|
||||||
if (fieldValue != null) {
|
|
||||||
Object value = extractValue(fieldValue);
|
|
||||||
joiner.add(field.getName() + " = " + (value instanceof String
|
|
||||||
|| value instanceof LocalDateTime ? "'" + value + "'" : value.toString()));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Constants.LOGGER.error("(REFLECTION) Error reading field: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qb.query.append(joiner).append(" ");
|
|
||||||
return qb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Añade una cláusula ORDER BY a la consulta actual, ordenando por la columna y el orden especificados.
|
|
||||||
* Si la columna no es válida, se ignora.
|
|
||||||
*
|
|
||||||
* @param column la columna por la que ordenar
|
|
||||||
* @param order el orden (ASC o DESC); si no se especifica, se asume ASC
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
*/
|
|
||||||
public QueryBuilder orderBy(Optional<String> column, Optional<String> order) {
|
public QueryBuilder orderBy(Optional<String> column, Optional<String> order) {
|
||||||
column.ifPresent(c -> {
|
column.ifPresent(c -> {
|
||||||
if (entityClass != null) {
|
if (entityClass != null) {
|
||||||
boolean isValid = Arrays.stream(entityClass.getDeclaredFields())
|
boolean valid = Arrays.stream(entityClass.getDeclaredFields())
|
||||||
.map(Field::getName)
|
.map(QueryBuilder::getColumnName)
|
||||||
.anyMatch(f -> f.equals(c));
|
.anyMatch(f -> f.equals(c));
|
||||||
|
if (!valid) {
|
||||||
if (!isValid) {
|
LOGGER.warn("[QueryBuilder] Ignorando campo invalido en ORDER BY: {}", c);
|
||||||
Constants.LOGGER.warn("[QueryBuilder] Ignorando campo invalido en ORDER BY: {}", c);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
orderByClause = "ORDER BY " + c + " " + order.orElse("ASC") + " ";
|
||||||
sort = "ORDER BY " + c + " ";
|
|
||||||
order.ifPresent(o -> sort += o.equalsIgnoreCase("asc") ? "ASC" : "DESC" + " ");
|
|
||||||
});
|
});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Añade una cláusula LIMIT a la consulta actual, limitando el número de resultados.
|
|
||||||
* Si se especifica un offset, se añade también.
|
|
||||||
*
|
|
||||||
* @param limitParam el número máximo de resultados a devolver; si no se especifica, no se aplica límite
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
*/
|
|
||||||
public QueryBuilder limit(Optional<Integer> limitParam) {
|
public QueryBuilder limit(Optional<Integer> limitParam) {
|
||||||
limitParam.ifPresent(param -> limit = "LIMIT " + param + " ");
|
limitParam.ifPresent(l -> limitClause = "LIMIT " + l + " ");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Añade una cláusula OFFSET a la consulta actual, desplazando el inicio de los resultados.
|
|
||||||
* Si se especifica un offset, se añade también.
|
|
||||||
*
|
|
||||||
* @param offsetParam el número de resultados a omitir antes de empezar a devolver resultados; si no se especifica, no se aplica offset
|
|
||||||
* @return el QueryBuilder actual para encadenar más métodos
|
|
||||||
*/
|
|
||||||
public QueryBuilder offset(Optional<Integer> offsetParam) {
|
public QueryBuilder offset(Optional<Integer> offsetParam) {
|
||||||
offsetParam.ifPresent(param -> limit += "OFFSET " + param + " ");
|
offsetParam.ifPresent(o -> offsetClause = "OFFSET " + o + " ");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construye y devuelve la consulta SQL completa.
|
|
||||||
* Si no se han añadido cláusulas ORDER BY, LIMIT o OFFSET, las omite.
|
|
||||||
*
|
|
||||||
* @return la consulta SQL construida
|
|
||||||
*/
|
|
||||||
public String build() {
|
public String build() {
|
||||||
if (order != null && !order.isEmpty()) {
|
if (orderByClause != null) query.append(orderByClause);
|
||||||
query.append(order);
|
if (limitClause != null) query.append(limitClause);
|
||||||
}
|
if (offsetClause != null) query.append(offsetClause);
|
||||||
if (sort != null && !sort.isEmpty()) {
|
|
||||||
query.append(sort);
|
|
||||||
}
|
|
||||||
if (limit != null && !limit.isEmpty()) {
|
|
||||||
query.append(limit);
|
|
||||||
}
|
|
||||||
return query.toString().trim() + ";";
|
return query.toString().trim() + ";";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.miarma.api.backlib.gson;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public class GsonProvider {
|
||||||
|
private static final Gson INSTANCE = createGson();
|
||||||
|
private static Gson createGson() {
|
||||||
|
return new GsonBuilder()
|
||||||
|
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
|
||||||
|
.registerTypeAdapter(JsonObject.class, new JsonObjectTypeAdapter())
|
||||||
|
.registerTypeHierarchyAdapter(IValuableEnum.class, new ValuableEnumDeserializer())
|
||||||
|
.registerTypeHierarchyAdapter(IValuableEnum.class, new ValuableEnumTypeAdapter())
|
||||||
|
.addSerializationExclusionStrategy(new APIDontReturnExclusionStrategy())
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Gson get() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GsonProvider() {}
|
||||||
|
}
|
||||||
@@ -4,7 +4,8 @@ import com.google.gson.JsonDeserializationContext;
|
|||||||
import com.google.gson.JsonDeserializer;
|
import com.google.gson.JsonDeserializer;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import net.miarma.api.backlib.ValuableEnum;
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -15,15 +16,15 @@ import java.util.Arrays;
|
|||||||
*
|
*
|
||||||
* @author José Manuel Amador Gallardo
|
* @author José Manuel Amador Gallardo
|
||||||
*/
|
*/
|
||||||
public class ValuableEnumDeserializer implements JsonDeserializer<ValuableEnum> {
|
public class ValuableEnumDeserializer implements JsonDeserializer<IValuableEnum> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValuableEnum deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
public IValuableEnum deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
Class<?> enumClass = (Class<?>) typeOfT;
|
Class<?> enumClass = (Class<?>) typeOfT;
|
||||||
int value = json.getAsInt();
|
int value = json.getAsInt();
|
||||||
|
|
||||||
return (ValuableEnum) Arrays.stream(enumClass.getEnumConstants())
|
return (IValuableEnum) Arrays.stream(enumClass.getEnumConstants())
|
||||||
.filter(e -> ((ValuableEnum) e).getValue() == value)
|
.filter(e -> ((IValuableEnum) e).getValue() == value)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow(() -> new JsonParseException("Invalid enum value: " + value));
|
.orElseThrow(() -> new JsonParseException("Invalid enum value: " + value));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import com.google.gson.JsonElement;
|
|||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
import com.google.gson.JsonSerializationContext;
|
import com.google.gson.JsonSerializationContext;
|
||||||
import com.google.gson.JsonSerializer;
|
import com.google.gson.JsonSerializer;
|
||||||
import net.miarma.api.backlib.ValuableEnum;
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
@@ -14,10 +15,10 @@ import java.lang.reflect.Type;
|
|||||||
*
|
*
|
||||||
* @author José Manuel Amador Gallardo
|
* @author José Manuel Amador Gallardo
|
||||||
*/
|
*/
|
||||||
public class ValuableEnumTypeAdapter implements JsonSerializer<ValuableEnum> {
|
public class ValuableEnumTypeAdapter implements JsonSerializer<IValuableEnum> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonElement serialize(ValuableEnum src, Type typeOfSrc, JsonSerializationContext context) {
|
public JsonElement serialize(IValuableEnum src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
return new JsonPrimitive(src.getValue());
|
return new JsonPrimitive(src.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package net.miarma.api.backlib.interfaces;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserGlobalStatus;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
|
||||||
|
|
||||||
public interface IUser {
|
|
||||||
Integer getUser_id();
|
|
||||||
String getUser_name();
|
|
||||||
String getEmail();
|
|
||||||
String getDisplay_name();
|
|
||||||
String getPassword();
|
|
||||||
String getAvatar();
|
|
||||||
CoreUserGlobalStatus getGlobal_status();
|
|
||||||
CoreUserRole getGlobal_role();
|
|
||||||
LocalDateTime getCreated_at();
|
|
||||||
default LocalDateTime getUpdated_at() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
package net.miarma.api.backlib.interfaces;
|
package net.miarma.api.backlib.interfaces;
|
||||||
|
|
||||||
import net.miarma.api.backlib.ValuableEnum;
|
public interface IUserRole extends IValuableEnum {
|
||||||
|
|
||||||
public interface IUserRole extends ValuableEnum {
|
|
||||||
String name();
|
String name();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package net.miarma.api.backlib;
|
package net.miarma.api.backlib.interfaces;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interfaz que define un enum con un valor entero asociado
|
* Interfaz que define un enum con un valor entero asociado
|
||||||
* @author José Manuel Amador Gallardo
|
* @author José Manuel Amador Gallardo
|
||||||
*/
|
*/
|
||||||
public interface ValuableEnum {
|
public interface IValuableEnum {
|
||||||
int getValue();
|
int getValue();
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.backlib;
|
package net.miarma.api.backlib.log;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.backlib;
|
package net.miarma.api.backlib.log;
|
||||||
|
|
||||||
public record LogEntry(int order, String message) {
|
public record LogEntry(int order, String message) {
|
||||||
public static LogEntry of(int order, String message) {
|
public static LogEntry of(int order, String message) {
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package net.miarma.api.backlib.log;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class LoggerProvider {
|
||||||
|
public static Logger getLogger() {
|
||||||
|
String className = Thread.currentThread().getStackTrace()[2].getClassName();
|
||||||
|
return LoggerFactory.getLogger(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.miarma.api.backlib.middlewares;
|
package net.miarma.api.backlib.middlewares;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
@@ -14,11 +15,11 @@ import net.miarma.api.backlib.util.JsonUtil;
|
|||||||
* Maneja extracción de JWT y verificación básica.
|
* Maneja extracción de JWT y verificación básica.
|
||||||
* Los microservicios solo implementan getUserEntity y hasPermission.
|
* Los microservicios solo implementan getUserEntity y hasPermission.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked") // arreglar el warning de heap pollution de los arrays de genéricos
|
@SuppressWarnings("unchecked")
|
||||||
public abstract class AbstractAuthGuard<U, R extends Enum<R> & IUserRole> {
|
public abstract class AbstractAuthGuard<U, R extends Enum<R> & IUserRole> {
|
||||||
|
|
||||||
protected abstract R parseRole(String roleStr);
|
protected abstract R parseRole(String roleStr);
|
||||||
protected abstract void getUserEntity(int userId, RoutingContext ctx, Consumer<U> callback);
|
protected abstract void getUserEntity(UUID userId, RoutingContext ctx, Consumer<U> callback);
|
||||||
protected abstract boolean hasPermission(U user, R role);
|
protected abstract boolean hasPermission(U user, R role);
|
||||||
|
|
||||||
public Handler<RoutingContext> check(R... allowedRoles) {
|
public Handler<RoutingContext> check(R... allowedRoles) {
|
||||||
@@ -29,7 +30,7 @@ public abstract class AbstractAuthGuard<U, R extends Enum<R> & IUserRole> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int userId = JWTManager.getInstance().extractUserId(token);
|
UUID userId = JWTManager.getInstance().extractUserId(token);
|
||||||
String roleStr = JWTManager.getInstance().extractRole(token);
|
String roleStr = JWTManager.getInstance().extractRole(token);
|
||||||
|
|
||||||
R role;
|
R role;
|
||||||
@@ -59,14 +60,11 @@ public abstract class AbstractAuthGuard<U, R extends Enum<R> & IUserRole> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isRoleAllowed(R role, R... allowedRoles) {
|
protected boolean isRoleAllowed(R role, R... allowedRoles) {
|
||||||
for (R allowed : allowedRoles) {
|
for (R allowed : allowedRoles) if (role == allowed) return true; return false;
|
||||||
if (role == allowed) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractToken(RoutingContext ctx) {
|
protected String extractToken(RoutingContext ctx) {
|
||||||
String authHeader = ctx.request().getHeader("Authorization");
|
String authHeader = ctx.request().getHeader("Authorization");
|
||||||
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
||||||
return authHeader.substring(7);
|
return authHeader.substring(7);
|
||||||
|
|||||||
@@ -1,23 +1,14 @@
|
|||||||
package net.miarma.api.backlib.security;
|
package net.miarma.api.backlib.security;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
import com.auth0.jwt.JWT;
|
import com.auth0.jwt.JWT;
|
||||||
import com.auth0.jwt.algorithms.Algorithm;
|
import com.auth0.jwt.algorithms.Algorithm;
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
import com.auth0.jwt.interfaces.JWTVerifier;
|
import com.auth0.jwt.interfaces.JWTVerifier;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.interfaces.IUserRole;
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clase de gestión de JSON Web Tokens (JWT).
|
|
||||||
* Proporciona métodos para generar, verificar y decodificar tokens JWT.
|
|
||||||
* <p>
|
|
||||||
* Esta clase sigue el patron Singleton para asegurar una sola instancia.
|
|
||||||
*
|
|
||||||
* @author José Manuel Amador Gallardo
|
|
||||||
*/
|
|
||||||
public class JWTManager {
|
public class JWTManager {
|
||||||
|
|
||||||
private final ConfigManager config = ConfigManager.getInstance();
|
private final ConfigManager config = ConfigManager.getInstance();
|
||||||
@@ -30,11 +21,6 @@ public class JWTManager {
|
|||||||
this.verifier = JWT.require(algorithm).build();
|
this.verifier = JWT.require(algorithm).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtiene la instancia única de JWTManager.
|
|
||||||
*
|
|
||||||
* @return La instancia única de JWTManager.
|
|
||||||
*/
|
|
||||||
public static synchronized JWTManager getInstance() {
|
public static synchronized JWTManager getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new JWTManager();
|
instance = new JWTManager();
|
||||||
@@ -43,113 +29,54 @@ public class JWTManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Genera un token JWT para un usuario.
|
* Genera un token JWT usando UUID para el usuario.
|
||||||
*
|
|
||||||
* @param user El usuario para el cual se generará el token.
|
|
||||||
* @param keepLoggedIn Indica si el token debe tener una duración prolongada.
|
|
||||||
* @return El token JWT generado.
|
|
||||||
*/
|
*/
|
||||||
public String generateToken(String user_name, Integer user_id, CoreUserRole role, boolean keepLoggedIn) {
|
public String generateToken(
|
||||||
final long EXPIRATION_TIME_MS = 1000L * (keepLoggedIn ? config.getIntProperty("jwt.expiration") : config.getIntProperty("jwt.expiration.short"));
|
String displayName,
|
||||||
|
UUID userId,
|
||||||
|
IUserRole role,
|
||||||
|
Integer serviceId,
|
||||||
|
boolean keepLoggedIn
|
||||||
|
) {
|
||||||
|
final long expiration = 1000L * (
|
||||||
|
keepLoggedIn
|
||||||
|
? config.getIntProperty("jwt.expiration")
|
||||||
|
: config.getIntProperty("jwt.expiration.short")
|
||||||
|
);
|
||||||
|
|
||||||
return JWT.create()
|
return JWT.create()
|
||||||
.withSubject(user_name)
|
.withSubject(displayName)
|
||||||
.withClaim("userId", user_id)
|
.withClaim("userId", userId.toString())
|
||||||
|
.withClaim("serviceId", serviceId)
|
||||||
.withClaim("role", role.name())
|
.withClaim("role", role.name())
|
||||||
.withClaim("isAdmin", role == Constants.CoreUserRole.ADMIN)
|
|
||||||
.withIssuedAt(new Date())
|
.withIssuedAt(new Date())
|
||||||
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME_MS))
|
.withExpiresAt(new Date(System.currentTimeMillis() + expiration))
|
||||||
.sign(algorithm);
|
.sign(algorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public DecodedJWT decode(String token) {
|
||||||
* Decodifica un token JWT sin verificar su firma.
|
|
||||||
*
|
|
||||||
* @param token El token JWT a decodificar.
|
|
||||||
* @return Un objeto DecodedJWT que contiene la información del token.
|
|
||||||
*/
|
|
||||||
public DecodedJWT decodeWithoutVerification(String token) {
|
|
||||||
return JWT.decode(token);
|
return JWT.decode(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public UUID extractUserId(String token) {
|
||||||
* Verifica la validez de un token JWT.
|
|
||||||
*
|
|
||||||
* @param token El token JWT a verificar.
|
|
||||||
* @return true si el token es válido, false en caso contrario.
|
|
||||||
*/
|
|
||||||
public boolean isValid(String token) {
|
|
||||||
try {
|
|
||||||
verifier.verify(token);
|
|
||||||
return true;
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifica si un token JWT pertenece a un usuario administrador.
|
|
||||||
*
|
|
||||||
* @param token El token JWT a verificar.
|
|
||||||
* @return true si el token pertenece a un administrador, false en caso contrario.
|
|
||||||
*/
|
|
||||||
public boolean isAdmin(String token) {
|
|
||||||
try {
|
try {
|
||||||
DecodedJWT jwt = verifier.verify(token);
|
DecodedJWT jwt = verifier.verify(token);
|
||||||
return jwt.getClaim("isAdmin").asBoolean();
|
String uuidStr = jwt.getClaim("userId").asString();
|
||||||
} catch (Exception e) {
|
return UUID.fromString(uuidStr);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtiene el ID de usuario a partir de un token JWT.
|
|
||||||
*
|
|
||||||
* @param token El token JWT del cual se extraerá el ID de usuario.
|
|
||||||
* @return El ID de usuario si el token es válido, -1 en caso contrario.
|
|
||||||
*/
|
|
||||||
public int getUserId(String token) {
|
|
||||||
try {
|
|
||||||
DecodedJWT jwt = verifier.verify(token);
|
|
||||||
return jwt.getClaim("userId").asInt();
|
|
||||||
} catch (Exception e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtiene el sub especificado en un token JWT, que generalmente es el nombre de usuario.
|
|
||||||
*
|
|
||||||
* @param token El token JWT del cual se extraerá el nombre de usuario.
|
|
||||||
* @return El nombre de usuario si el token es válido, null en caso contrario.
|
|
||||||
*/
|
|
||||||
public String getSubject(String token) {
|
|
||||||
try {
|
|
||||||
DecodedJWT jwt = verifier.verify(token);
|
|
||||||
return jwt.getSubject();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public Integer extractServiceId(String token) {
|
||||||
* Extrae el ID de usuario de un token JWT.
|
|
||||||
* @param token El token JWT del cual se extraerá el ID de usuario.
|
|
||||||
* @return El ID de usuario si el token es válido, -1 en caso contrario.
|
|
||||||
*/
|
|
||||||
public int extractUserId(String token) {
|
|
||||||
try {
|
try {
|
||||||
DecodedJWT jwt = verifier.verify(token);
|
DecodedJWT jwt = verifier.verify(token);
|
||||||
return jwt.getClaim("userId").asInt();
|
return jwt.getClaim("serviceId").asInt();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Extrae el rol de usuario de un token JWT.
|
|
||||||
* @param token El token JWT del cual se extraerá el ID de usuario.
|
|
||||||
* @return El rol de usuario si el token es válido, null en caso contrario.
|
|
||||||
*/
|
|
||||||
public String extractRole(String token) {
|
public String extractRole(String token) {
|
||||||
try {
|
try {
|
||||||
DecodedJWT jwt = verifier.verify(token);
|
DecodedJWT jwt = verifier.verify(token);
|
||||||
@@ -158,4 +85,13 @@ public class JWTManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isValid(String token) {
|
||||||
|
try {
|
||||||
|
verifier.verify(token);
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
package net.miarma.api.backlib.security;
|
package net.miarma.api.backlib.security;
|
||||||
|
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,6 +8,8 @@ import java.security.SecureRandom;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clase encargada de generar los secrets necesarios para la autenticación JWT.
|
* Clase encargada de generar los secrets necesarios para la autenticación JWT.
|
||||||
* Si el secret ya existe en el archivo de configuración, lo devuelve.
|
* Si el secret ya existe en el archivo de configuración, lo devuelve.
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package net.miarma.api.backlib.util;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.vertx.core.buffer.Buffer;
|
||||||
|
|
||||||
|
public class BufferUtil {
|
||||||
|
public static UUID uuidFromBuffer(Buffer b) {
|
||||||
|
if (b == null || b.length() != 16) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
long mostSigBits = b.getLong(0);
|
||||||
|
long leastSigBits = b.getLong(8);
|
||||||
|
return new UUID(mostSigBits, leastSigBits);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ package net.miarma.api.backlib.util;
|
|||||||
import io.vertx.core.json.JsonArray;
|
import io.vertx.core.json.JsonArray;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.gson.GsonProvider;
|
||||||
import net.miarma.api.backlib.http.ApiResponse;
|
import net.miarma.api.backlib.http.ApiResponse;
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ public class JsonUtil {
|
|||||||
.put("data", data);
|
.put("data", data);
|
||||||
ctx.response().end(response.encode());
|
ctx.response().end(response.encode());
|
||||||
} else {
|
} else {
|
||||||
ctx.response().end(Constants.GSON.toJson(new ApiResponse<>(status, message, data)));
|
ctx.response().end(GsonProvider.get().toJson(new ApiResponse<>(status, message, data)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
package net.miarma.api.backlib.util;
|
package net.miarma.api.backlib.util;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clase de utilidad para adjuntar un logger a un router de Vert.x.
|
* Clase de utilidad para adjuntar un logger a un router de Vert.x.
|
||||||
* @author José Manuel Amador Gallardo
|
* @author José Manuel Amador Gallardo
|
||||||
*/
|
*/
|
||||||
public class RouterUtil {
|
public class RouterUtil {
|
||||||
|
private final static Logger LOGGER = LoggerProvider.getLogger();
|
||||||
|
|
||||||
public static void attachLogger(Router router) {
|
public static void attachLogger(Router router) {
|
||||||
router.route().handler(ctx -> {
|
router.route().handler(ctx -> {
|
||||||
@@ -46,7 +49,7 @@ public class RouterUtil {
|
|||||||
duration
|
duration
|
||||||
);
|
);
|
||||||
|
|
||||||
Constants.LOGGER.info(log);
|
LOGGER.info(log);
|
||||||
});
|
});
|
||||||
|
|
||||||
ctx.next();
|
ctx.next();
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>miarma-ecosystem</artifactId>
|
<artifactId>miarma-backend</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>bootstrap</artifactId>
|
<artifactId>bootstrap</artifactId>
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>huertos</artifactId>
|
<artifactId>huertos</artifactId>
|
||||||
@@ -51,7 +52,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>miarmacraft</artifactId>
|
<artifactId>minecraft</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -59,10 +60,11 @@
|
|||||||
<artifactId>mpaste</artifactId>
|
<artifactId>mpaste</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
-->
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<finalName>MiarmaEcosystem</finalName>
|
<finalName>MiarmaBackend</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package net.miarma.api;
|
package net.miarma.api;
|
||||||
|
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.security.SecretManager;
|
|
||||||
import net.miarma.api.backlib.vertx.VertxJacksonConfig;
|
|
||||||
import net.miarma.api.backlib.util.MessageUtil;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import io.vertx.core.Launcher;
|
import io.vertx.core.Launcher;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
|
import net.miarma.api.backlib.security.SecretManager;
|
||||||
|
import net.miarma.api.backlib.util.MessageUtil;
|
||||||
|
import net.miarma.api.backlib.vertx.VertxJacksonConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Punto de entrada para inicializar la aplicación.
|
* Punto de entrada para inicializar la aplicación.
|
||||||
@@ -24,12 +25,13 @@ import io.vertx.core.Launcher;
|
|||||||
* - Desplegar el Verticle Master
|
* - Desplegar el Verticle Master
|
||||||
*/
|
*/
|
||||||
public class AppInitializer {
|
public class AppInitializer {
|
||||||
|
private final static Logger LOGGER = LoggerProvider.getLogger();
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
AppInitializer initializer = new AppInitializer();
|
AppInitializer initializer = new AppInitializer();
|
||||||
initializer.init();
|
initializer.init();
|
||||||
initializer.deployMaster();
|
initializer.deployMaster();
|
||||||
Constants.LOGGER.info("✅ App initialized successfully!");
|
LOGGER.info("✅ App initialized successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ConfigManager configManager;
|
private final ConfigManager configManager;
|
||||||
@@ -49,7 +51,7 @@ public class AppInitializer {
|
|||||||
private void initializeDirectories() {
|
private void initializeDirectories() {
|
||||||
File baseDir = new File(configManager.getBaseDir());
|
File baseDir = new File(configManager.getBaseDir());
|
||||||
if (!baseDir.exists() && baseDir.mkdirs()) {
|
if (!baseDir.exists() && baseDir.mkdirs()) {
|
||||||
Constants.LOGGER.info("Created base directory: " + baseDir.getAbsolutePath());
|
LOGGER.info("Created base directory: " + baseDir.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,12 +61,12 @@ public class AppInitializer {
|
|||||||
try (InputStream in = getClass().getClassLoader().getResourceAsStream("default.properties")) {
|
try (InputStream in = getClass().getClassLoader().getResourceAsStream("default.properties")) {
|
||||||
if (in != null) {
|
if (in != null) {
|
||||||
Files.copy(in, configFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(in, configFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
Constants.LOGGER.info("Copied default.properties to: " + configFile.getAbsolutePath());
|
LOGGER.info("Copied default.properties to: " + configFile.getAbsolutePath());
|
||||||
} else {
|
} else {
|
||||||
Constants.LOGGER.error(MessageUtil.notFound("Default config", "resources"));
|
LOGGER.error(MessageUtil.notFound("Default config", "resources"));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Constants.LOGGER.error(MessageUtil.failedTo("copy", "default config", e));
|
LOGGER.error(MessageUtil.failedTo("copy", "default config", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,38 @@
|
|||||||
package net.miarma.api;
|
package net.miarma.api;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
import io.vertx.core.AbstractVerticle;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.log.LogAccumulator;
|
||||||
import net.miarma.api.backlib.LogAccumulator;
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
import net.miarma.api.backlib.util.DeploymentUtil;
|
import net.miarma.api.backlib.util.DeploymentUtil;
|
||||||
import net.miarma.api.microservices.core.verticles.CoreMainVerticle;
|
import net.miarma.api.microservices.core.verticles.CoreMainVerticle;
|
||||||
import net.miarma.api.microservices.huertos.verticles.HuertosMainVerticle;
|
//import net.miarma.api.microservices.huertos.verticles.HuertosMainVerticle;
|
||||||
import net.miarma.api.microservices.huertosdecine.verticles.CineMainVerticle;
|
//import net.miarma.api.microservices.huertosdecine.verticles.CineMainVerticle;
|
||||||
import net.miarma.api.microservices.miarmacraft.verticles.MMCMainVerticle;
|
//import net.miarma.api.microservices.minecraft.verticles.MMCMainVerticle;
|
||||||
import net.miarma.api.microservices.mpaste.verticles.MPasteMainVerticle;
|
//import net.miarma.api.microservices.mpaste.verticles.MPasteMainVerticle;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public class MasterVerticle extends AbstractVerticle {
|
public class MasterVerticle extends AbstractVerticle {
|
||||||
|
private final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Promise<Void> startPromise) {
|
public void start(Promise<Void> startPromise) {
|
||||||
deploy()
|
deploy()
|
||||||
.onSuccess(v -> {
|
.onSuccess(v -> {
|
||||||
vertx.setTimer(300, id -> {
|
vertx.setTimer(300, id -> {
|
||||||
LogAccumulator.flushToLogger(Constants.LOGGER);
|
LogAccumulator.flushToLogger(LOGGER);
|
||||||
startPromise.complete();
|
startPromise.complete();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.onFailure(startPromise::fail);
|
.onFailure(startPromise::fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private Future<Void> deploy() {
|
private Future<Void> deploy() {
|
||||||
Promise<Void> promise = Promise.promise();
|
Promise<Void> promise = Promise.promise();
|
||||||
|
|
||||||
@@ -34,7 +40,7 @@ public class MasterVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(id -> LogAccumulator.add(DeploymentUtil.successMessage(CoreMainVerticle.class)))
|
.onSuccess(id -> LogAccumulator.add(DeploymentUtil.successMessage(CoreMainVerticle.class)))
|
||||||
.onFailure(err -> LogAccumulator.add(DeploymentUtil.failMessage(CoreMainVerticle.class, err)));
|
.onFailure(err -> LogAccumulator.add(DeploymentUtil.failMessage(CoreMainVerticle.class, err)));
|
||||||
|
|
||||||
Future<String> huertos = vertx.deployVerticle(new HuertosMainVerticle())
|
/*Future<String> huertos = vertx.deployVerticle(new HuertosMainVerticle())
|
||||||
.onSuccess(id -> LogAccumulator.add(DeploymentUtil.successMessage(HuertosMainVerticle.class)))
|
.onSuccess(id -> LogAccumulator.add(DeploymentUtil.successMessage(HuertosMainVerticle.class)))
|
||||||
.onFailure(err -> LogAccumulator.add(DeploymentUtil.failMessage(HuertosMainVerticle.class, err)));
|
.onFailure(err -> LogAccumulator.add(DeploymentUtil.failMessage(HuertosMainVerticle.class, err)));
|
||||||
|
|
||||||
@@ -48,9 +54,10 @@ public class MasterVerticle extends AbstractVerticle {
|
|||||||
|
|
||||||
Future<String> mpaste = vertx.deployVerticle(new MPasteMainVerticle())
|
Future<String> mpaste = vertx.deployVerticle(new MPasteMainVerticle())
|
||||||
.onSuccess(id -> LogAccumulator.add(DeploymentUtil.successMessage(MPasteMainVerticle.class)))
|
.onSuccess(id -> LogAccumulator.add(DeploymentUtil.successMessage(MPasteMainVerticle.class)))
|
||||||
.onFailure(err -> LogAccumulator.add(DeploymentUtil.failMessage(MPasteMainVerticle.class, err)));
|
.onFailure(err -> LogAccumulator.add(DeploymentUtil.failMessage(MPasteMainVerticle.class, err)));*/
|
||||||
|
|
||||||
Future.all(core, huertos, mmc, cine, mpaste)
|
//Future.all(core, huertos, mmc, cine, mpaste)
|
||||||
|
Future.all(List.of(core))
|
||||||
.onSuccess(_ -> promise.complete())
|
.onSuccess(_ -> promise.complete())
|
||||||
.onFailure(promise::fail);
|
.onFailure(promise::fail);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,25 @@
|
|||||||
|
# App Configuration
|
||||||
|
app.name=miarma-backend
|
||||||
|
app.version=v2
|
||||||
|
|
||||||
|
# API Configuration
|
||||||
|
api.base=/api
|
||||||
|
|
||||||
|
api.core.prefix=/core/${app.version}
|
||||||
|
api.auth.prefix=/auth/${app.version}
|
||||||
|
api.huertos.prefix=/huertos/${app.version}
|
||||||
|
api.minecraft.prefix=/minecraft/${app.version}
|
||||||
|
api.cine.prefix=/cine/${app.version}
|
||||||
|
api.mpaste.prefix=/mpaste/${app.version}
|
||||||
|
|
||||||
|
# EventBus Configuration
|
||||||
|
eventbus.auth.address=auth.eventbus
|
||||||
|
eventbus.core.address=core.eventbus
|
||||||
|
eventbus.huertos.address=huertos.eventbus
|
||||||
|
eventbus.minecraft.address=minecraft.eventbus
|
||||||
|
eventbus.cine.address=cine.eventbus
|
||||||
|
eventbus.mpaste.address=mpaste.eventbus
|
||||||
|
|
||||||
# DB Configuration
|
# DB Configuration
|
||||||
db.protocol=jdbc:mariadb
|
db.protocol=jdbc:mariadb
|
||||||
db.host=localhost
|
db.host=localhost
|
||||||
@@ -9,10 +31,10 @@ dp.poolSize=5
|
|||||||
|
|
||||||
# HTTP Server Configuration
|
# HTTP Server Configuration
|
||||||
inet.host=localhost
|
inet.host=localhost
|
||||||
sso.logic.port=8080
|
core.logic.port=8080
|
||||||
sso.data.port=8081
|
core.data.port=8081
|
||||||
mmc.logic.port=8100
|
minecraft.logic.port=8100
|
||||||
mmc.data.port=8101
|
minecraft.data.port=8101
|
||||||
huertos.logic.port=8120
|
huertos.logic.port=8120
|
||||||
huertos.data.port=8121
|
huertos.data.port=8121
|
||||||
cine.data.port = 8140
|
cine.data.port = 8140
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>23</maven.compiler.source>
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
@@ -20,35 +20,8 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>backlib</artifactId>
|
<artifactId>backlib</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>ME-Core</finalName>
|
|
||||||
<plugins>
|
|
||||||
<!-- Maven Shade Plugin -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.5.3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<transformers>
|
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
|
||||||
<mainClass>net.miarma.api.microservices.core.verticles.CoreMainVerticle</mainClass>
|
|
||||||
</transformer>
|
|
||||||
</transformers>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
package net.miarma.api.microservices.core.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.core.Promise;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import net.miarma.api.microservices.core.entities.CredentialEntity;
|
||||||
|
import net.miarma.api.backlib.db.DataAccessObject;
|
||||||
|
import net.miarma.api.backlib.db.DatabaseManager;
|
||||||
|
import net.miarma.api.backlib.db.QueryBuilder;
|
||||||
|
import net.miarma.api.backlib.http.QueryFilters;
|
||||||
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
|
|
||||||
|
public class CredentialDAO implements DataAccessObject<CredentialEntity, UUID> {
|
||||||
|
|
||||||
|
private final DatabaseManager db;
|
||||||
|
|
||||||
|
public CredentialDAO(Pool pool) {
|
||||||
|
this.db = DatabaseManager.getInstance(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<List<CredentialEntity>> getAll() {
|
||||||
|
return getAll(new QueryParams(Map.of(), new QueryFilters()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<CredentialEntity> getById(UUID id) {
|
||||||
|
Promise<CredentialEntity> promise = Promise.promise();
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select(CredentialEntity.class)
|
||||||
|
.where(Map.of("credential_id", id.toString()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
db.executeOne(query, CredentialEntity.class,
|
||||||
|
promise::complete,
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<List<CredentialEntity>> getAll(QueryParams params) {
|
||||||
|
Promise<List<CredentialEntity>> promise = Promise.promise();
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select(CredentialEntity.class)
|
||||||
|
.where(params.getFilters())
|
||||||
|
.orderBy(params.getQueryFilters().getSort(), params.getQueryFilters().getOrder())
|
||||||
|
.limit(params.getQueryFilters().getLimit())
|
||||||
|
.offset(params.getQueryFilters().getOffset())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
db.execute(query, CredentialEntity.class,
|
||||||
|
list -> promise.complete(list.isEmpty() ? List.of() : list),
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Útil para el login: busca la credencial por servicio y usuario
|
||||||
|
*/
|
||||||
|
public Future<CredentialEntity> getByServiceAndUsername(int serviceId, String username) {
|
||||||
|
Promise<CredentialEntity> promise = Promise.promise();
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select(CredentialEntity.class)
|
||||||
|
.where(Map.of("service_id", String.valueOf(serviceId), "username", username))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
db.executeOne(query, CredentialEntity.class,
|
||||||
|
promise::complete,
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<List<CredentialEntity>> getByUserId(UUID userId) {
|
||||||
|
Promise<List<CredentialEntity>> promise = Promise.promise();
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select(CredentialEntity.class)
|
||||||
|
.where(Map.of("user_id", userId.toString()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
db.execute(query, CredentialEntity.class,
|
||||||
|
promise::complete,
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<CredentialEntity> insert(CredentialEntity credential) {
|
||||||
|
Promise<CredentialEntity> promise = Promise.promise();
|
||||||
|
// Si no tiene ID, se lo generamos antes de insertar
|
||||||
|
if (credential.getCredentialId() == null) {
|
||||||
|
credential.setCredentialId(UUID.randomUUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
String query = QueryBuilder.insert(credential).build();
|
||||||
|
|
||||||
|
db.executeOne(query, CredentialEntity.class,
|
||||||
|
promise::complete,
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<CredentialEntity> upsert(CredentialEntity credential, String... conflictKeys) {
|
||||||
|
Promise<CredentialEntity> promise = Promise.promise();
|
||||||
|
String query = QueryBuilder.upsert(credential, conflictKeys).build();
|
||||||
|
|
||||||
|
db.executeOne(query, CredentialEntity.class,
|
||||||
|
promise::complete,
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<CredentialEntity> update(CredentialEntity credential) {
|
||||||
|
Promise<CredentialEntity> promise = Promise.promise();
|
||||||
|
String query = QueryBuilder.update(credential).build();
|
||||||
|
|
||||||
|
db.executeOne(query, CredentialEntity.class,
|
||||||
|
_ -> promise.complete(credential),
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<Boolean> delete(UUID id) {
|
||||||
|
Promise<Boolean> promise = Promise.promise();
|
||||||
|
CredentialEntity cred = new CredentialEntity();
|
||||||
|
cred.setCredentialId(id);
|
||||||
|
|
||||||
|
String query = QueryBuilder.delete(cred).build();
|
||||||
|
|
||||||
|
db.executeOne(query, CredentialEntity.class,
|
||||||
|
result -> promise.complete(result != null),
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future<Boolean> exists(UUID id) {
|
||||||
|
Promise<Boolean> promise = Promise.promise();
|
||||||
|
String query = QueryBuilder
|
||||||
|
.select(CredentialEntity.class)
|
||||||
|
.where(Map.of("credential_id", id.toString()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
db.executeOne(query, CredentialEntity.class,
|
||||||
|
result -> promise.complete(result != null),
|
||||||
|
promise::fail
|
||||||
|
);
|
||||||
|
|
||||||
|
return promise.future();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
package net.miarma.api.backlib.core.dao;
|
package net.miarma.api.microservices.core.dao;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
@@ -8,12 +12,9 @@ import net.miarma.api.backlib.db.DatabaseManager;
|
|||||||
import net.miarma.api.backlib.db.QueryBuilder;
|
import net.miarma.api.backlib.db.QueryBuilder;
|
||||||
import net.miarma.api.backlib.http.QueryFilters;
|
import net.miarma.api.backlib.http.QueryFilters;
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
import net.miarma.api.backlib.core.entities.FileEntity;
|
import net.miarma.api.microservices.core.entities.FileEntity;
|
||||||
|
|
||||||
import java.util.List;
|
public class FileDAO implements DataAccessObject<FileEntity, UUID> {
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class FileDAO implements DataAccessObject<FileEntity, Integer> {
|
|
||||||
|
|
||||||
private final DatabaseManager db;
|
private final DatabaseManager db;
|
||||||
|
|
||||||
@@ -27,7 +28,7 @@ public class FileDAO implements DataAccessObject<FileEntity, Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<FileEntity> getById(Integer id) {
|
public Future<FileEntity> getById(UUID id) {
|
||||||
Promise<FileEntity> promise = Promise.promise();
|
Promise<FileEntity> promise = Promise.promise();
|
||||||
String query = QueryBuilder
|
String query = QueryBuilder
|
||||||
.select(FileEntity.class)
|
.select(FileEntity.class)
|
||||||
@@ -60,7 +61,7 @@ public class FileDAO implements DataAccessObject<FileEntity, Integer> {
|
|||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<List<FileEntity>> getUserFiles(Integer userId) {
|
public Future<List<FileEntity>> getUserFiles(UUID userId) {
|
||||||
Promise<List<FileEntity>> promise = Promise.promise();
|
Promise<List<FileEntity>> promise = Promise.promise();
|
||||||
String query = QueryBuilder
|
String query = QueryBuilder
|
||||||
.select(FileEntity.class)
|
.select(FileEntity.class)
|
||||||
@@ -115,7 +116,7 @@ public class FileDAO implements DataAccessObject<FileEntity, Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<Boolean> exists(Integer id) {
|
public Future<Boolean> exists(UUID id) {
|
||||||
Promise<Boolean> promise = Promise.promise();
|
Promise<Boolean> promise = Promise.promise();
|
||||||
String query = QueryBuilder
|
String query = QueryBuilder
|
||||||
.select(FileEntity.class)
|
.select(FileEntity.class)
|
||||||
@@ -131,10 +132,10 @@ public class FileDAO implements DataAccessObject<FileEntity, Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<Boolean> delete(Integer id) {
|
public Future<Boolean> delete(UUID id) {
|
||||||
Promise<Boolean> promise = Promise.promise();
|
Promise<Boolean> promise = Promise.promise();
|
||||||
FileEntity file = new FileEntity();
|
FileEntity file = new FileEntity();
|
||||||
file.setFile_id(id);
|
file.setFileId(id);
|
||||||
|
|
||||||
String query = QueryBuilder.delete(file).build();
|
String query = QueryBuilder.delete(file).build();
|
||||||
|
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
package net.miarma.api.backlib.core.dao;
|
package net.miarma.api.microservices.core.dao;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.core.entities.UserEntity;
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
import net.miarma.api.backlib.db.DataAccessObject;
|
import net.miarma.api.backlib.db.DataAccessObject;
|
||||||
import net.miarma.api.backlib.db.DatabaseManager;
|
import net.miarma.api.backlib.db.DatabaseManager;
|
||||||
import net.miarma.api.backlib.db.QueryBuilder;
|
import net.miarma.api.backlib.db.QueryBuilder;
|
||||||
import net.miarma.api.backlib.http.QueryFilters;
|
import net.miarma.api.backlib.http.QueryFilters;
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
|
|
||||||
public class UserDAO implements DataAccessObject<UserEntity, Integer> {
|
public class UserDAO implements DataAccessObject<UserEntity, UUID> {
|
||||||
|
|
||||||
private final DatabaseManager db;
|
private final DatabaseManager db;
|
||||||
|
|
||||||
@@ -27,13 +28,15 @@ public class UserDAO implements DataAccessObject<UserEntity, Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<UserEntity> getById(Integer id) {
|
public Future<UserEntity> getById(UUID id) {
|
||||||
Promise<UserEntity> promise = Promise.promise();
|
Promise<UserEntity> promise = Promise.promise();
|
||||||
String query = QueryBuilder
|
String query = QueryBuilder
|
||||||
.select(UserEntity.class)
|
.select(UserEntity.class)
|
||||||
.where(Map.of("user_id", id.toString()))
|
.where(Map.of("user_id", id))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
System.out.println(query);
|
||||||
|
|
||||||
db.executeOne(query, UserEntity.class,
|
db.executeOne(query, UserEntity.class,
|
||||||
promise::complete,
|
promise::complete,
|
||||||
promise::fail
|
promise::fail
|
||||||
@@ -60,36 +63,6 @@ public class UserDAO implements DataAccessObject<UserEntity, Integer> {
|
|||||||
return promise.future();
|
return promise.future();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<UserEntity> getByEmail(String email) {
|
|
||||||
Promise<UserEntity> promise = Promise.promise();
|
|
||||||
String query = QueryBuilder
|
|
||||||
.select(UserEntity.class)
|
|
||||||
.where(Map.of("email", email))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
db.executeOne(query, UserEntity.class,
|
|
||||||
promise::complete,
|
|
||||||
promise::fail
|
|
||||||
);
|
|
||||||
|
|
||||||
return promise.future();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future<UserEntity> getByUserName(String userName) {
|
|
||||||
Promise<UserEntity> promise = Promise.promise();
|
|
||||||
String query = QueryBuilder
|
|
||||||
.select(UserEntity.class)
|
|
||||||
.where(Map.of("user_name", userName))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
db.executeOne(query, UserEntity.class,
|
|
||||||
promise::complete,
|
|
||||||
promise::fail
|
|
||||||
);
|
|
||||||
|
|
||||||
return promise.future();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<UserEntity> insert(UserEntity user) {
|
public Future<UserEntity> insert(UserEntity user) {
|
||||||
Promise<UserEntity> promise = Promise.promise();
|
Promise<UserEntity> promise = Promise.promise();
|
||||||
@@ -130,10 +103,10 @@ public class UserDAO implements DataAccessObject<UserEntity, Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<Boolean> delete(Integer id) {
|
public Future<Boolean> delete(UUID id) {
|
||||||
Promise<Boolean> promise = Promise.promise();
|
Promise<Boolean> promise = Promise.promise();
|
||||||
UserEntity user = new UserEntity();
|
UserEntity user = new UserEntity();
|
||||||
user.setUser_id(id);
|
user.setUserId(id);
|
||||||
|
|
||||||
String query = QueryBuilder.delete(user).build();
|
String query = QueryBuilder.delete(user).build();
|
||||||
|
|
||||||
@@ -146,7 +119,7 @@ public class UserDAO implements DataAccessObject<UserEntity, Integer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Future<Boolean> exists(Integer id) {
|
public Future<Boolean> exists(UUID id) {
|
||||||
Promise<Boolean> promise = Promise.promise();
|
Promise<Boolean> promise = Promise.promise();
|
||||||
String query = QueryBuilder
|
String query = QueryBuilder
|
||||||
.select(UserEntity.class)
|
.select(UserEntity.class)
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
package net.miarma.api.microservices.core.entities;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import io.vertx.sqlclient.Row;
|
||||||
|
import net.miarma.api.backlib.annotations.APIDontReturn;
|
||||||
|
import net.miarma.api.backlib.annotations.Table;
|
||||||
|
import net.miarma.api.backlib.db.AbstractEntity;
|
||||||
|
|
||||||
|
@Table("credentials")
|
||||||
|
public class CredentialEntity extends AbstractEntity {
|
||||||
|
|
||||||
|
@SerializedName("credential_id")
|
||||||
|
private UUID credentialId;
|
||||||
|
|
||||||
|
@SerializedName("user_id")
|
||||||
|
private UUID userId;
|
||||||
|
|
||||||
|
@SerializedName("service_id")
|
||||||
|
private int serviceId;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@APIDontReturn
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private int status;
|
||||||
|
|
||||||
|
@SerializedName("created_at")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@SerializedName("updated_at")
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
public CredentialEntity() { }
|
||||||
|
public CredentialEntity(Row row) { super(row); }
|
||||||
|
|
||||||
|
public UUID getCredentialId() {
|
||||||
|
return credentialId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCredentialId(UUID credentialId) {
|
||||||
|
this.credentialId = credentialId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserId(UUID userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getServiceId() {
|
||||||
|
return serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServiceId(int serviceId) {
|
||||||
|
this.serviceId = 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 int getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(LocalDateTime createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getUpdatedAt() {
|
||||||
|
return updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUpdatedAt(LocalDateTime updatedAt) {
|
||||||
|
this.updatedAt = updatedAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package net.miarma.api.microservices.core.entities;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import io.vertx.sqlclient.Row;
|
||||||
|
import net.miarma.api.backlib.annotations.Table;
|
||||||
|
import net.miarma.api.backlib.db.AbstractEntity;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreFileContext;
|
||||||
|
|
||||||
|
@Table("files")
|
||||||
|
public class FileEntity extends AbstractEntity {
|
||||||
|
|
||||||
|
@SerializedName("file_id")
|
||||||
|
private UUID fileId;
|
||||||
|
|
||||||
|
@SerializedName("file_name")
|
||||||
|
private String fileName;
|
||||||
|
|
||||||
|
@SerializedName("file_path")
|
||||||
|
private String filePath;
|
||||||
|
|
||||||
|
@SerializedName("mime_type")
|
||||||
|
private String mimeType;
|
||||||
|
|
||||||
|
@SerializedName("uploaded_by")
|
||||||
|
private UUID uploadedBy;
|
||||||
|
|
||||||
|
private CoreFileContext context;
|
||||||
|
|
||||||
|
@SerializedName("uploaded_at")
|
||||||
|
private LocalDateTime uploadedAt;
|
||||||
|
|
||||||
|
public FileEntity() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileEntity(Row row) {
|
||||||
|
super(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getFileId() {
|
||||||
|
return fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileId(UUID fileId) {
|
||||||
|
this.fileId = fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileName(String fileName) {
|
||||||
|
this.fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilePath() {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilePath(String filePath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMimeType() {
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMimeType(String mimeType) {
|
||||||
|
this.mimeType = mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getUploadedBy() {
|
||||||
|
return uploadedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUploadedBy(UUID uploadedBy) {
|
||||||
|
this.uploadedBy = uploadedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CoreFileContext getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(CoreFileContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getUploadedAt() {
|
||||||
|
return uploadedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUploadedAt(LocalDateTime uploadedAt) {
|
||||||
|
this.uploadedAt = uploadedAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package net.miarma.api.microservices.core.entities;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import io.vertx.sqlclient.Row;
|
||||||
|
import net.miarma.api.backlib.annotations.Table;
|
||||||
|
import net.miarma.api.backlib.db.AbstractEntity;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalRole;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalStatus;
|
||||||
|
|
||||||
|
@Table("users")
|
||||||
|
public class UserEntity extends AbstractEntity {
|
||||||
|
@SerializedName("user_id")
|
||||||
|
private UUID userId;
|
||||||
|
|
||||||
|
@SerializedName("display_name")
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
@SerializedName("global_status")
|
||||||
|
private CoreUserGlobalStatus globalStatus;
|
||||||
|
|
||||||
|
@SerializedName("global_role")
|
||||||
|
private CoreUserGlobalRole globalRole;
|
||||||
|
|
||||||
|
@SerializedName("created_at")
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@SerializedName("updated_at")
|
||||||
|
private LocalDateTime updatedAt;
|
||||||
|
|
||||||
|
public UserEntity() { }
|
||||||
|
public UserEntity(Row row) { super(row); }
|
||||||
|
|
||||||
|
public UUID getUserId() { return userId; }
|
||||||
|
public void setUserId(UUID userId) { this.userId = userId; }
|
||||||
|
|
||||||
|
public String getDisplayName() { return displayName; }
|
||||||
|
public void setDisplayName(String displayName) { this.displayName = displayName; }
|
||||||
|
|
||||||
|
public String getAvatar() { return avatar; }
|
||||||
|
public void setAvatar(String avatar) { this.avatar = avatar; }
|
||||||
|
|
||||||
|
public CoreUserGlobalStatus getGlobalStatus() { return globalStatus; }
|
||||||
|
public void setGlobalStatus(CoreUserGlobalStatus globalStatus) { this.globalStatus = globalStatus; }
|
||||||
|
|
||||||
|
public CoreUserGlobalRole getGlobalRole() { return globalRole; }
|
||||||
|
public void setGlobalRole(CoreUserGlobalRole role) { this.globalRole = role; }
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() { return createdAt; }
|
||||||
|
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
|
||||||
|
|
||||||
|
public LocalDateTime getUpdatedAt() { return updatedAt; }
|
||||||
|
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package net.miarma.api.microservices.core.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum CoreFileContext implements IValuableEnum {
|
||||||
|
CORE(0),
|
||||||
|
HUERTOS(1),
|
||||||
|
MMC(2),
|
||||||
|
CINE(3);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
CoreFileContext(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toCtxString() {
|
||||||
|
return switch(this) {
|
||||||
|
case CORE -> "core";
|
||||||
|
case HUERTOS -> "huertos";
|
||||||
|
case MMC -> "miarmacraft";
|
||||||
|
case CINE -> "cine";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CoreFileContext fromInt(int i) {
|
||||||
|
for (CoreFileContext context : values()) {
|
||||||
|
if (context.value == i) return context;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid CoreFileContext value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.miarma.api.microservices.core.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IUserRole;
|
||||||
|
|
||||||
|
public enum CoreUserGlobalRole implements IUserRole {
|
||||||
|
USER(0),
|
||||||
|
ADMIN(1);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
CoreUserGlobalRole(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CoreUserGlobalRole fromInt(int i) {
|
||||||
|
for (CoreUserGlobalRole role : values()) {
|
||||||
|
if (role.value == i) return role;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid CoreUserGlobalRole value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.miarma.api.microservices.core.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum CoreUserGlobalStatus implements IValuableEnum {
|
||||||
|
INACTIVE(0),
|
||||||
|
ACTIVE(1);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
CoreUserGlobalStatus(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CoreUserGlobalStatus fromInt(int i) {
|
||||||
|
for (CoreUserGlobalStatus status : values()) {
|
||||||
|
if (status.value == i) return status;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid CoreUserGlobalStatus value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
package net.miarma.api.microservices.core.handlers;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import io.vertx.core.Vertx;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
import net.miarma.api.backlib.gson.GsonProvider;
|
||||||
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
|
import net.miarma.api.backlib.security.JWTManager;
|
||||||
|
import net.miarma.api.backlib.util.EventBusUtil;
|
||||||
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class AuthHandler {
|
||||||
|
|
||||||
|
private final Gson GSON = GsonProvider.get();
|
||||||
|
private final Vertx vertx;
|
||||||
|
private final String AUTH_EVENT_BUS = ConfigManager.getInstance()
|
||||||
|
.getStringProperty("eventbus.auth.address");
|
||||||
|
|
||||||
|
public AuthHandler(Vertx vertx) {
|
||||||
|
this.vertx = vertx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void login(RoutingContext ctx) {
|
||||||
|
vertx.eventBus().request(AUTH_EVENT_BUS, ctx.body().asJsonObject().put("action", "login"))
|
||||||
|
.onSuccess(reply -> JsonUtil.sendJson(ctx, ApiStatus.OK, reply.body()))
|
||||||
|
.onFailure(err -> EventBusUtil.handleReplyError(ctx, err));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loginValidate(RoutingContext ctx) {
|
||||||
|
JsonObject body = ctx.body().asJsonObject();
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "loginValidate")
|
||||||
|
.put("userId", body.getInteger("userId"))
|
||||||
|
.put("password", body.getString("password"));
|
||||||
|
|
||||||
|
vertx.eventBus().request(AUTH_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateToken(RoutingContext ctx) {
|
||||||
|
String authHeader = ctx.request().getHeader("Authorization");
|
||||||
|
|
||||||
|
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
||||||
|
String token = authHeader.substring(7);
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "validateToken")
|
||||||
|
.put("token", token);
|
||||||
|
|
||||||
|
vertx.eventBus().request(AUTH_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded() && Boolean.TRUE.equals(ar.result().body())) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, true, "Valid token");
|
||||||
|
} else {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, false, "Invalid token");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.BAD_REQUEST, null, "Missing or invalid Authorization header");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshToken(RoutingContext ctx) {
|
||||||
|
String tokenHeader = ctx.request().getHeader("Authorization");
|
||||||
|
|
||||||
|
if (tokenHeader == null || !tokenHeader.startsWith("Bearer ")) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Missing or invalid Authorization header");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = tokenHeader.substring("Bearer ".length());
|
||||||
|
JWTManager jwt = JWTManager.getInstance();
|
||||||
|
|
||||||
|
try {
|
||||||
|
DecodedJWT decoded = jwt.decode(token);
|
||||||
|
String userIdStr = decoded.getClaim("userId").asString();
|
||||||
|
|
||||||
|
if (userIdStr == null) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid token claims");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID userId = UUID.fromString(userIdStr);
|
||||||
|
|
||||||
|
vertx.eventBus().request(AUTH_EVENT_BUS, new JsonObject()
|
||||||
|
.put("action", "getUserById")
|
||||||
|
.put("userId", userId.toString()), ar -> {
|
||||||
|
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonObject userJson = (JsonObject) ar.result().body();
|
||||||
|
UserEntity user = GSON.fromJson(userJson.encode(), UserEntity.class);
|
||||||
|
|
||||||
|
String newToken = jwt.generateToken(
|
||||||
|
user.getDisplayName(),
|
||||||
|
user.getUserId(),
|
||||||
|
user.getGlobalRole(),
|
||||||
|
0,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, new JsonObject().put("token", newToken));
|
||||||
|
} else {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "User not found or service unavailable");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid token format");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changePassword(RoutingContext ctx) {
|
||||||
|
JsonObject body = ctx.body().asJsonObject();
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "changePassword")
|
||||||
|
.put("userId", body.getInteger("userId"))
|
||||||
|
.put("newPassword", body.getString("newPassword"));
|
||||||
|
|
||||||
|
vertx.eventBus().request(AUTH_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, true, "Updated");
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(RoutingContext ctx) {
|
||||||
|
vertx.eventBus().request(AUTH_EVENT_BUS, ctx.body().asJsonObject().put("action", "register"))
|
||||||
|
.onSuccess(reply -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, null))
|
||||||
|
.onFailure(err -> EventBusUtil.handleReplyError(ctx, err));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,33 @@
|
|||||||
package net.miarma.api.backlib.core.handlers;
|
package net.miarma.api.microservices.core.handlers;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import io.vertx.core.buffer.Buffer;
|
import io.vertx.core.buffer.Buffer;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.FileUpload;
|
import io.vertx.ext.web.FileUpload;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.gson.GsonProvider;
|
||||||
import net.miarma.api.backlib.Constants.CoreFileContext;
|
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
import net.miarma.api.backlib.core.entities.FileEntity;
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
import net.miarma.api.backlib.core.services.FileService;
|
|
||||||
import net.miarma.api.backlib.util.JsonUtil;
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
|
import net.miarma.api.microservices.core.entities.FileEntity;
|
||||||
import java.io.IOException;
|
import net.miarma.api.microservices.core.enums.CoreFileContext;
|
||||||
import java.nio.file.Files;
|
import net.miarma.api.microservices.core.services.FileService;
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class FileDataHandler {
|
public class FileDataHandler {
|
||||||
|
|
||||||
|
private final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
|
private final Gson GSON = GsonProvider.get();
|
||||||
private final FileService fileService;
|
private final FileService fileService;
|
||||||
|
|
||||||
public FileDataHandler(Pool pool) {
|
public FileDataHandler(Pool pool) {
|
||||||
@@ -35,7 +43,7 @@ public class FileDataHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void getById(RoutingContext ctx) {
|
public void getById(RoutingContext ctx) {
|
||||||
Integer fileId = Integer.parseInt(ctx.pathParam("file_id"));
|
UUID fileId = UUID.fromString(ctx.pathParam("file_id"));
|
||||||
|
|
||||||
fileService.getById(fileId)
|
fileService.getById(fileId)
|
||||||
.onSuccess(file -> JsonUtil.sendJson(ctx, ApiStatus.OK, file))
|
.onSuccess(file -> JsonUtil.sendJson(ctx, ApiStatus.OK, file))
|
||||||
@@ -46,7 +54,7 @@ public class FileDataHandler {
|
|||||||
try {
|
try {
|
||||||
String fileName = ctx.request().getFormAttribute("file_name");
|
String fileName = ctx.request().getFormAttribute("file_name");
|
||||||
String mimeType = ctx.request().getFormAttribute("mime_type");
|
String mimeType = ctx.request().getFormAttribute("mime_type");
|
||||||
int uploadedBy = Integer.parseInt(ctx.request().getFormAttribute("uploaded_by"));
|
UUID uploadedBy = UUID.fromString(ctx.request().getFormAttribute("uploaded_by"));
|
||||||
int contextValue = Integer.parseInt(ctx.request().getFormAttribute("context"));
|
int contextValue = Integer.parseInt(ctx.request().getFormAttribute("context"));
|
||||||
|
|
||||||
FileUpload upload = ctx.fileUploads().stream()
|
FileUpload upload = ctx.fileUploads().stream()
|
||||||
@@ -58,23 +66,23 @@ public class FileDataHandler {
|
|||||||
byte[] fileBinary = buffer.getBytes();
|
byte[] fileBinary = buffer.getBytes();
|
||||||
|
|
||||||
FileEntity file = new FileEntity();
|
FileEntity file = new FileEntity();
|
||||||
file.setFile_name(fileName);
|
file.setFileName(fileName);
|
||||||
file.setMime_type(mimeType);
|
file.setMimeType(mimeType);
|
||||||
file.setUploaded_by(uploadedBy);
|
file.setUploadedBy(uploadedBy);
|
||||||
file.setContext(CoreFileContext.fromInt(contextValue));
|
file.setContext(CoreFileContext.fromInt(contextValue));
|
||||||
|
|
||||||
fileService.create(file, fileBinary)
|
fileService.create(file, fileBinary)
|
||||||
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
|
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
|
||||||
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
|
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Constants.LOGGER.error(e.getMessage(), e);
|
LOGGER.error(e.getMessage(), e);
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.INTERNAL_SERVER_ERROR, null, e.getMessage());
|
JsonUtil.sendJson(ctx, ApiStatus.INTERNAL_SERVER_ERROR, null, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void update(RoutingContext ctx) {
|
public void update(RoutingContext ctx) {
|
||||||
FileEntity file = Constants.GSON.fromJson(ctx.body().asString(), FileEntity.class);
|
FileEntity file = GSON.fromJson(ctx.body().asString(), FileEntity.class);
|
||||||
|
|
||||||
fileService.update(file)
|
fileService.update(file)
|
||||||
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.OK, result))
|
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.OK, result))
|
||||||
@@ -82,14 +90,14 @@ public class FileDataHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void delete(RoutingContext ctx) {
|
public void delete(RoutingContext ctx) {
|
||||||
Integer fileId = Integer.parseInt(ctx.pathParam("file_id"));
|
UUID fileId = UUID.fromString(ctx.pathParam("file_id"));
|
||||||
JsonObject body = ctx.body().asJsonObject();
|
JsonObject body = ctx.body().asJsonObject();
|
||||||
String filePath = body.getString("file_path");
|
String filePath = body.getString("file_path");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(Paths.get(filePath));
|
Files.deleteIfExists(Paths.get(filePath));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Constants.LOGGER.error(e.getMessage(), e);
|
LOGGER.error(e.getMessage(), e);
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.INTERNAL_SERVER_ERROR, null, e.getMessage());
|
JsonUtil.sendJson(ctx, ApiStatus.INTERNAL_SERVER_ERROR, null, e.getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package net.miarma.api.backlib.core.handlers;
|
package net.miarma.api.microservices.core.handlers;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import io.vertx.core.Vertx;
|
import io.vertx.core.Vertx;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
import net.miarma.api.backlib.security.JWTManager;
|
import net.miarma.api.backlib.security.JWTManager;
|
||||||
import net.miarma.api.backlib.util.JsonUtil;
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
@@ -11,6 +13,8 @@ import net.miarma.api.backlib.util.JsonUtil;
|
|||||||
public class FileLogicHandler {
|
public class FileLogicHandler {
|
||||||
|
|
||||||
private final Vertx vertx;
|
private final Vertx vertx;
|
||||||
|
private final String CORE_EVENT_BUS = ConfigManager.getInstance()
|
||||||
|
.getStringProperty("eventbus.core.address");
|
||||||
|
|
||||||
public FileLogicHandler(Vertx vertx) {
|
public FileLogicHandler(Vertx vertx) {
|
||||||
this.vertx = vertx;
|
this.vertx = vertx;
|
||||||
@@ -25,14 +29,14 @@ public class FileLogicHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String token = authHeader.substring(7);
|
String token = authHeader.substring(7);
|
||||||
int userId = JWTManager.getInstance().getUserId(token);
|
UUID userId = JWTManager.getInstance().extractUserId(token);
|
||||||
|
|
||||||
if (userId <= 0) {
|
if (userId == null) {
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid token");
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid or expired token");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
request.put("userId", userId);
|
request.put("userId", userId.toString());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +44,7 @@ public class FileLogicHandler {
|
|||||||
JsonObject request = new JsonObject().put("action", "getUserFiles");
|
JsonObject request = new JsonObject().put("action", "getUserFiles");
|
||||||
if (!validateAuth(ctx, request)) return;
|
if (!validateAuth(ctx, request)) return;
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.CORE_EVENT_BUS, request, ar -> {
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
if (ar.succeeded()) {
|
if (ar.succeeded()) {
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
} else {
|
} else {
|
||||||
@@ -50,13 +54,15 @@ public class FileLogicHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void downloadFile(RoutingContext ctx) {
|
public void downloadFile(RoutingContext ctx) {
|
||||||
|
UUID fileId = UUID.fromString(ctx.pathParam("file_id"));
|
||||||
|
|
||||||
JsonObject request = new JsonObject()
|
JsonObject request = new JsonObject()
|
||||||
.put("action", "downloadFile")
|
.put("action", "downloadFile")
|
||||||
.put("fileId", Integer.parseInt(ctx.pathParam("file_id")));
|
.put("fileId", fileId.toString());
|
||||||
|
|
||||||
if (!validateAuth(ctx, request)) return;
|
if (!validateAuth(ctx, request)) return;
|
||||||
|
|
||||||
vertx.eventBus().request(Constants.CORE_EVENT_BUS, request, ar -> {
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
if (ar.succeeded()) {
|
if (ar.succeeded()) {
|
||||||
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
} else {
|
} else {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.backlib.core.handlers;
|
package net.miarma.api.microservices.core.handlers;
|
||||||
|
|
||||||
import io.vertx.core.Vertx;
|
import io.vertx.core.Vertx;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package net.miarma.api.microservices.core.handlers;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import net.miarma.api.backlib.gson.GsonProvider;
|
||||||
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
|
import net.miarma.api.microservices.core.services.UserService;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class UserDataHandler {
|
||||||
|
|
||||||
|
private final Gson GSON = GsonProvider.get();
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
public UserDataHandler(Pool pool) {
|
||||||
|
this.userService = new UserService(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getAll(RoutingContext ctx) {
|
||||||
|
userService.getAll(QueryParams.from(ctx))
|
||||||
|
.onSuccess(users -> JsonUtil.sendJson(ctx, ApiStatus.OK, users))
|
||||||
|
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getById(RoutingContext ctx) {
|
||||||
|
Future.succeededFuture(ctx.pathParam("user_id"))
|
||||||
|
.map(UUID::fromString)
|
||||||
|
.compose(userService::getById)
|
||||||
|
.onSuccess(user -> JsonUtil.sendJson(ctx, ApiStatus.OK, user))
|
||||||
|
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.BAD_REQUEST, null, "Invalid UUID format"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(RoutingContext ctx) {
|
||||||
|
Future.succeededFuture(ctx.body().asString())
|
||||||
|
.map(body -> GSON.fromJson(body, UserEntity.class))
|
||||||
|
.compose(userService::update)
|
||||||
|
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.OK, result))
|
||||||
|
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.BAD_REQUEST, null, "Invalid user data"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(RoutingContext ctx) {
|
||||||
|
Future.succeededFuture(ctx.pathParam("user_id"))
|
||||||
|
.map(UUID::fromString)
|
||||||
|
.compose(userService::delete)
|
||||||
|
.onSuccess(v -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
|
||||||
|
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.BAD_REQUEST, null, "Invalid UUID format"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package net.miarma.api.microservices.core.handlers;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.vertx.core.Vertx;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.ext.web.RoutingContext;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
|
import net.miarma.api.backlib.security.JWTManager;
|
||||||
|
import net.miarma.api.backlib.util.EventBusUtil;
|
||||||
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
|
|
||||||
|
public class UserLogicHandler {
|
||||||
|
|
||||||
|
private final String CORE_EVENT_BUS = ConfigManager.getInstance()
|
||||||
|
.getStringProperty("eventbus.core.address");
|
||||||
|
private final Vertx vertx;
|
||||||
|
|
||||||
|
public UserLogicHandler(Vertx vertx) {
|
||||||
|
this.vertx = vertx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getInfo(RoutingContext ctx) {
|
||||||
|
String authHeader = ctx.request().getHeader("Authorization");
|
||||||
|
|
||||||
|
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Unauthorized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = authHeader.substring(7);
|
||||||
|
UUID userId = JWTManager.getInstance().extractUserId(token);
|
||||||
|
|
||||||
|
if (userId == null) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, null, "Invalid token");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "getInfo")
|
||||||
|
.put("userId", userId);
|
||||||
|
|
||||||
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void exists(RoutingContext ctx) {
|
||||||
|
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "userExists")
|
||||||
|
.put("userId", userId);
|
||||||
|
|
||||||
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getStatus(RoutingContext ctx) {
|
||||||
|
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "getStatus")
|
||||||
|
.put("userId", userId);
|
||||||
|
|
||||||
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getRole(RoutingContext ctx) {
|
||||||
|
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "getRole")
|
||||||
|
.put("userId", userId);
|
||||||
|
|
||||||
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getAvatar(RoutingContext ctx) {
|
||||||
|
int userId = Integer.parseInt(ctx.pathParam("user_id"));
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "getAvatar")
|
||||||
|
.put("userId", userId);
|
||||||
|
|
||||||
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.OK, ar.result().body());
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateStatus(RoutingContext ctx) {
|
||||||
|
JsonObject body = ctx.body().asJsonObject();
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "updateStatus")
|
||||||
|
.put("userId", body.getInteger("userId"))
|
||||||
|
.put("status", body.getInteger("status"));
|
||||||
|
|
||||||
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null);
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateRole(RoutingContext ctx) {
|
||||||
|
JsonObject body = ctx.body().asJsonObject();
|
||||||
|
|
||||||
|
JsonObject request = new JsonObject()
|
||||||
|
.put("action", "updateRole")
|
||||||
|
.put("userId", body.getInteger("userId"))
|
||||||
|
.put("role", body.getInteger("role"));
|
||||||
|
|
||||||
|
vertx.eventBus().request(CORE_EVENT_BUS, request, ar -> {
|
||||||
|
if (ar.succeeded()) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null);
|
||||||
|
} else {
|
||||||
|
EventBusUtil.handleReplyError(ctx, ar.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,11 @@ import io.vertx.core.Vertx;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalRole;
|
||||||
import net.miarma.api.backlib.core.handlers.FileDataHandler;
|
import net.miarma.api.microservices.core.handlers.FileDataHandler;
|
||||||
import net.miarma.api.backlib.core.handlers.UserDataHandler;
|
import net.miarma.api.microservices.core.handlers.UserDataHandler;
|
||||||
import net.miarma.api.backlib.core.services.UserService;
|
|
||||||
import net.miarma.api.microservices.core.routing.middlewares.CoreAuthGuard;
|
import net.miarma.api.microservices.core.routing.middlewares.CoreAuthGuard;
|
||||||
|
import net.miarma.api.microservices.core.services.UserService;
|
||||||
|
|
||||||
public class CoreDataRouter {
|
public class CoreDataRouter {
|
||||||
public static void mount(Router router, Vertx vertx, Pool pool) {
|
public static void mount(Router router, Vertx vertx, Pool pool) {
|
||||||
@@ -19,17 +19,15 @@ public class CoreDataRouter {
|
|||||||
|
|
||||||
router.route().handler(BodyHandler.create());
|
router.route().handler(BodyHandler.create());
|
||||||
|
|
||||||
router.get(CoreEndpoints.USERS).handler(authGuard.check(CoreUserRole.ADMIN)).handler(hUserData::getAll);
|
router.get(CoreEndpoints.USERS).handler(authGuard.check(CoreUserGlobalRole.ADMIN)).handler(hUserData::getAll);
|
||||||
router.get(CoreEndpoints.USER).handler(authGuard.check(CoreUserRole.ADMIN)).handler(hUserData::getById);
|
router.get(CoreEndpoints.USER).handler(authGuard.check(CoreUserGlobalRole.ADMIN)).handler(hUserData::getById);
|
||||||
router.post(CoreEndpoints.USERS).handler(hUserData::create);
|
router.put(CoreEndpoints.USER).handler(authGuard.check(CoreUserGlobalRole.ADMIN)).handler(hUserData::update);
|
||||||
router.put(CoreEndpoints.USER).handler(authGuard.check(CoreUserRole.ADMIN)).handler(hUserData::update);
|
router.delete(CoreEndpoints.USER).handler(authGuard.check(CoreUserGlobalRole.ADMIN)).handler(hUserData::delete);
|
||||||
router.delete(CoreEndpoints.USER).handler(authGuard.check(CoreUserRole.ADMIN)).handler(hUserData::delete);
|
|
||||||
|
|
||||||
router.get(CoreEndpoints.FILES).handler(authGuard.check()).handler(hFileData::getAll);
|
router.get(CoreEndpoints.FILES).handler(authGuard.check(CoreUserGlobalRole.ADMIN)).handler(hFileData::getAll);
|
||||||
router.get(CoreEndpoints.FILE).handler(authGuard.check()).handler(hFileData::getById);
|
router.get(CoreEndpoints.FILE).handler(authGuard.check()).handler(hFileData::getById);
|
||||||
router.post(CoreEndpoints.FILE_UPLOAD).handler(authGuard.check()).handler(hFileData::create);
|
router.post(CoreEndpoints.FILE_UPLOAD).handler(authGuard.check()).handler(hFileData::create);
|
||||||
router.put(CoreEndpoints.FILE).handler(authGuard.check()).handler(hFileData::update);
|
router.put(CoreEndpoints.FILE).handler(authGuard.check()).handler(hFileData::update);
|
||||||
router.delete(CoreEndpoints.FILE).handler(authGuard.check()).handler(hFileData::delete);
|
router.delete(CoreEndpoints.FILE).handler(authGuard.check()).handler(hFileData::delete);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,36 @@
|
|||||||
package net.miarma.api.microservices.core.routing;
|
package net.miarma.api.microservices.core.routing;
|
||||||
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
|
||||||
public class CoreEndpoints {
|
public class CoreEndpoints {
|
||||||
|
|
||||||
/*
|
private static final ConfigManager config = ConfigManager.getInstance();
|
||||||
* RUTAS DE LA API DE DATOS
|
private static final String CORE = config.getApiPrefix("core");
|
||||||
* DE NEGOCIO DEL SSO
|
private static final String AUTH = config.getApiPrefix("auth");
|
||||||
*/
|
|
||||||
|
|
||||||
// Usuarios
|
/* API DE DATOS (UserDataHandler / FileDataHandler) */
|
||||||
public static final String USERS = Constants.CORE_PREFIX + "/users"; // GET, POST, PUT, DELETE
|
public static final String USERS = CORE + "/users";
|
||||||
public static final String USER = Constants.CORE_PREFIX + "/users/:user_id"; // GET, PUT, DELETE
|
public static final String USER = CORE + "/users/:user_id";
|
||||||
public static final String USER_STATUS = Constants.CORE_PREFIX + "/users/:user_id/status"; // GET, PUT
|
public static final String FILES = CORE + "/files";
|
||||||
public static final String USER_ROLE = Constants.CORE_PREFIX + "/users/:user_id/role"; // GET, PUT
|
public static final String FILE = CORE + "/files/:file_id";
|
||||||
public static final String USER_EXISTS = Constants.CORE_PREFIX + "/users/:user_id/exists"; // GET
|
public static final String FILE_UPLOAD = CORE + "/files/upload";
|
||||||
public static final String USER_AVATAR = Constants.CORE_PREFIX + "/users/:user_id/avatar"; // GET, PUT
|
|
||||||
public static final String USER_INFO = Constants.CORE_PREFIX + "/users/me"; // GET
|
|
||||||
|
|
||||||
// Archivos
|
/* API DE LÓGICA (AuthHandler / UserLogicHandler / FileLogicHandler) */
|
||||||
public static final String FILES = Constants.CORE_PREFIX + "/files"; // GET, POST
|
public static final String LOGIN = AUTH + "/login";
|
||||||
public static final String FILE = Constants.CORE_PREFIX + "/files/:file_id"; // GET, PUT, DELETE
|
public static final String LOGIN_VALID = AUTH + "/login/validate";
|
||||||
public static final String FILE_UPLOAD = Constants.CORE_PREFIX + "/files/upload"; // POST
|
public static final String REGISTER = AUTH + "/register";
|
||||||
public static final String FILE_DOWNLOAD = Constants.CORE_PREFIX + "/files/:file_id/download"; // GET
|
public static final String CHANGE_PASSWORD = AUTH + "/change-password";
|
||||||
public static final String USER_FILES = Constants.CORE_PREFIX + "/files/myfiles"; // GET
|
public static final String VALIDATE_TOKEN = AUTH + "/validate-token";
|
||||||
|
public static final String REFRESH_TOKEN = AUTH + "/refresh-token";
|
||||||
|
|
||||||
/*
|
public static final String USER_INFO = CORE + "/users/me";
|
||||||
* RUTAS DE LA API DE LOGICA
|
public static final String USER_STATUS = CORE + "/users/:user_id/status";
|
||||||
* DE NEGOCIO DEL SSO
|
public static final String USER_ROLE = CORE + "/users/:user_id/role";
|
||||||
*/
|
public static final String USER_EXISTS = CORE + "/users/:user_id/exists";
|
||||||
public static final String LOGIN = Constants.AUTH_PREFIX + "/login"; // POST
|
public static final String USER_AVATAR = CORE + "/users/:user_id/avatar";
|
||||||
public static final String LOGIN_VALID = Constants.AUTH_PREFIX + "/login/validate"; // POST
|
|
||||||
public static final String REGISTER = Constants.AUTH_PREFIX + "/register"; // POST
|
public static final String FILE_DOWNLOAD = CORE + "/files/:file_id/download";
|
||||||
public static final String CHANGE_PASSWORD = Constants.AUTH_PREFIX + "/change-password"; // POST
|
public static final String USER_FILES = CORE + "/files/myfiles";
|
||||||
public static final String VALIDATE_TOKEN = Constants.AUTH_PREFIX + "/validate-token"; // POST
|
|
||||||
public static final String REFRESH_TOKEN = Constants.AUTH_PREFIX + "/refresh-token"; // POST
|
public static final String SCREENSHOT = CORE + "/screenshot";
|
||||||
public static final String SCREENSHOT = Constants.CORE_PREFIX + "/screenshot"; // GET
|
|
||||||
}
|
}
|
||||||
@@ -4,36 +4,40 @@ import io.vertx.core.Vertx;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalRole;
|
||||||
import net.miarma.api.backlib.core.handlers.FileLogicHandler;
|
import net.miarma.api.microservices.core.handlers.AuthHandler;
|
||||||
import net.miarma.api.backlib.core.handlers.ScreenshotHandler;
|
import net.miarma.api.microservices.core.handlers.FileLogicHandler;
|
||||||
import net.miarma.api.backlib.core.handlers.UserLogicHandler;
|
import net.miarma.api.microservices.core.handlers.ScreenshotHandler;
|
||||||
import net.miarma.api.backlib.core.services.UserService;
|
import net.miarma.api.microservices.core.handlers.UserLogicHandler;
|
||||||
import net.miarma.api.microservices.core.routing.middlewares.CoreAuthGuard;
|
import net.miarma.api.microservices.core.routing.middlewares.CoreAuthGuard;
|
||||||
|
import net.miarma.api.microservices.core.services.UserService;
|
||||||
|
|
||||||
public class CoreLogicRouter {
|
public class CoreLogicRouter {
|
||||||
public static void mount(Router router, Vertx vertx, Pool pool) {
|
public static void mount(Router router, Vertx vertx, Pool pool) {
|
||||||
UserLogicHandler hUserLogic = new UserLogicHandler(vertx);
|
UserLogicHandler hUserLogic = new UserLogicHandler(vertx);
|
||||||
FileLogicHandler hFileLogic = new FileLogicHandler(vertx);
|
FileLogicHandler hFileLogic = new FileLogicHandler(vertx);
|
||||||
|
AuthHandler hAuth = new AuthHandler(vertx);
|
||||||
ScreenshotHandler hScreenshot = new ScreenshotHandler(vertx);
|
ScreenshotHandler hScreenshot = new ScreenshotHandler(vertx);
|
||||||
|
|
||||||
UserService userService = new UserService(pool);
|
UserService userService = new UserService(pool);
|
||||||
CoreAuthGuard authGuard = new CoreAuthGuard(userService);
|
CoreAuthGuard authGuard = new CoreAuthGuard(userService);
|
||||||
|
|
||||||
router.route().handler(BodyHandler.create());
|
router.route().handler(BodyHandler.create());
|
||||||
|
|
||||||
router.post(CoreEndpoints.LOGIN).handler(hUserLogic::login);
|
router.post(CoreEndpoints.LOGIN).handler(hAuth::login);
|
||||||
router.get(CoreEndpoints.USER_INFO).handler(authGuard.check()).handler(hUserLogic::getInfo);
|
router.post(CoreEndpoints.REGISTER).handler(hAuth::register);
|
||||||
router.post(CoreEndpoints.REGISTER).handler(hUserLogic::register);
|
router.post(CoreEndpoints.LOGIN_VALID).handler(hAuth::loginValidate);
|
||||||
router.post(CoreEndpoints.CHANGE_PASSWORD).handler(authGuard.check()).handler(hUserLogic::changePassword);
|
|
||||||
router.post(CoreEndpoints.LOGIN_VALID).handler(hUserLogic::loginValidate);
|
|
||||||
router.get(CoreEndpoints.VALIDATE_TOKEN).handler(hUserLogic::validateToken);
|
|
||||||
router.get(CoreEndpoints.REFRESH_TOKEN).handler(hUserLogic::refreshToken);
|
|
||||||
|
|
||||||
|
router.get(CoreEndpoints.VALIDATE_TOKEN).handler(authGuard.check()).handler(hAuth::validateToken);
|
||||||
|
router.get(CoreEndpoints.REFRESH_TOKEN).handler(hAuth::refreshToken);
|
||||||
|
router.post(CoreEndpoints.CHANGE_PASSWORD).handler(authGuard.check()).handler(hAuth::changePassword);
|
||||||
|
|
||||||
|
router.get(CoreEndpoints.USER_INFO).handler(authGuard.check()).handler(hUserLogic::getInfo);
|
||||||
router.get(CoreEndpoints.USER_EXISTS).handler(authGuard.check()).handler(hUserLogic::exists);
|
router.get(CoreEndpoints.USER_EXISTS).handler(authGuard.check()).handler(hUserLogic::exists);
|
||||||
router.get(CoreEndpoints.USER_STATUS).handler(authGuard.check()).handler(hUserLogic::getStatus);
|
router.get(CoreEndpoints.USER_STATUS).handler(authGuard.check()).handler(hUserLogic::getStatus);
|
||||||
router.put(CoreEndpoints.USER_STATUS).handler(authGuard.check(CoreUserRole.ADMIN)).handler(hUserLogic::updateStatus);
|
router.put(CoreEndpoints.USER_STATUS).handler(authGuard.check(CoreUserGlobalRole.ADMIN)).handler(hUserLogic::updateStatus);
|
||||||
router.get(CoreEndpoints.USER_ROLE).handler(authGuard.check()).handler(hUserLogic::getRole);
|
router.get(CoreEndpoints.USER_ROLE).handler(authGuard.check()).handler(hUserLogic::getRole);
|
||||||
router.put(CoreEndpoints.USER_ROLE).handler(authGuard.check(CoreUserRole.ADMIN)).handler(hUserLogic::updateRole);
|
router.put(CoreEndpoints.USER_ROLE).handler(authGuard.check(CoreUserGlobalRole.ADMIN)).handler(hUserLogic::updateRole);
|
||||||
router.get(CoreEndpoints.USER_AVATAR).handler(authGuard.check()).handler(hUserLogic::getAvatar);
|
router.get(CoreEndpoints.USER_AVATAR).handler(authGuard.check()).handler(hUserLogic::getAvatar);
|
||||||
|
|
||||||
router.get(CoreEndpoints.FILE_DOWNLOAD).handler(authGuard.check()).handler(hFileLogic::downloadFile);
|
router.get(CoreEndpoints.FILE_DOWNLOAD).handler(authGuard.check()).handler(hFileLogic::downloadFile);
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package net.miarma.api.microservices.core.routing.middlewares;
|
package net.miarma.api.microservices.core.routing.middlewares;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
|
||||||
import net.miarma.api.backlib.middlewares.AbstractAuthGuard;
|
import net.miarma.api.backlib.middlewares.AbstractAuthGuard;
|
||||||
import net.miarma.api.backlib.core.entities.UserEntity;
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
import net.miarma.api.backlib.core.services.UserService;
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalRole;
|
||||||
|
import net.miarma.api.microservices.core.services.UserService;
|
||||||
|
|
||||||
public class CoreAuthGuard extends AbstractAuthGuard<UserEntity, CoreUserRole> {
|
public class CoreAuthGuard extends AbstractAuthGuard<UserEntity, CoreUserGlobalRole> {
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
public CoreAuthGuard(UserService userService) {
|
public CoreAuthGuard(UserService userService) {
|
||||||
@@ -16,12 +17,12 @@ public class CoreAuthGuard extends AbstractAuthGuard<UserEntity, CoreUserRole> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CoreUserRole parseRole(String roleStr) {
|
protected CoreUserGlobalRole parseRole(String roleStr) {
|
||||||
return CoreUserRole.valueOf(roleStr.toUpperCase());
|
return CoreUserGlobalRole.valueOf(roleStr.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void getUserEntity(int userId, RoutingContext ctx, Consumer<UserEntity> callback) {
|
protected void getUserEntity(UUID userId, RoutingContext ctx, Consumer<UserEntity> callback) {
|
||||||
userService.getById(userId).onComplete(ar -> {
|
userService.getById(userId).onComplete(ar -> {
|
||||||
if (ar.succeeded()) callback.accept(ar.result());
|
if (ar.succeeded()) callback.accept(ar.result());
|
||||||
else callback.accept(null);
|
else callback.accept(null);
|
||||||
@@ -29,7 +30,8 @@ public class CoreAuthGuard extends AbstractAuthGuard<UserEntity, CoreUserRole> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasPermission(UserEntity user, CoreUserRole role) {
|
protected boolean hasPermission(UserEntity user, CoreUserGlobalRole userRole) {
|
||||||
return user.getGlobal_role() == CoreUserRole.ADMIN;
|
return user.getGlobalRole() == CoreUserGlobalRole.ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package net.miarma.api.microservices.core.services;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import net.miarma.api.backlib.exceptions.BadRequestException;
|
||||||
|
import net.miarma.api.backlib.exceptions.ForbiddenException;
|
||||||
|
import net.miarma.api.backlib.exceptions.NotFoundException;
|
||||||
|
import net.miarma.api.backlib.security.JWTManager;
|
||||||
|
import net.miarma.api.backlib.security.PasswordHasher;
|
||||||
|
import net.miarma.api.microservices.core.dao.CredentialDAO;
|
||||||
|
import net.miarma.api.microservices.core.dao.UserDAO;
|
||||||
|
import net.miarma.api.microservices.core.entities.CredentialEntity;
|
||||||
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalRole;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalStatus;
|
||||||
|
|
||||||
|
public class AuthService {
|
||||||
|
|
||||||
|
private final UserDAO userDAO;
|
||||||
|
private final CredentialDAO credentialDAO;
|
||||||
|
private final int serviceId;
|
||||||
|
|
||||||
|
public AuthService(Pool pool, int serviceId) {
|
||||||
|
this.userDAO = new UserDAO(pool);
|
||||||
|
this.credentialDAO = new CredentialDAO(pool);
|
||||||
|
this.serviceId = serviceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Login: Comprueba credenciales y devuelve el token + datos del usuario
|
||||||
|
*/
|
||||||
|
public Future<JsonObject> login(String login, String plainPassword, boolean keepLoggedIn) {
|
||||||
|
return credentialDAO.getByServiceAndUsername(this.serviceId, login).compose(cred -> {
|
||||||
|
if (cred == null) {
|
||||||
|
return Future.failedFuture(new NotFoundException("User not found in this domain"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PasswordHasher.verify(plainPassword, cred.getPassword())) {
|
||||||
|
return Future.failedFuture(new BadRequestException("Invalid credentials"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return userDAO.getById(cred.getUserId()).compose(user -> {
|
||||||
|
if (user == null) {
|
||||||
|
return Future.failedFuture(new NotFoundException("User not found"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.getGlobalStatus() != CoreUserGlobalStatus.ACTIVE) {
|
||||||
|
return Future.failedFuture(new ForbiddenException("User is inactive"));
|
||||||
|
}
|
||||||
|
|
||||||
|
String token = JWTManager.getInstance().generateToken(
|
||||||
|
cred.getUsername(),
|
||||||
|
user.getUserId(),
|
||||||
|
user.getGlobalRole(),
|
||||||
|
this.serviceId,
|
||||||
|
keepLoggedIn
|
||||||
|
);
|
||||||
|
|
||||||
|
JsonObject response = new JsonObject()
|
||||||
|
.put("token", token)
|
||||||
|
.put("user", JsonObject.mapFrom(user));
|
||||||
|
|
||||||
|
return Future.succeededFuture(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register: Crea el perfil global y la credencial de servicio
|
||||||
|
*/
|
||||||
|
public Future<UserEntity> register(UserEntity profile, String username, String email, String password) {
|
||||||
|
profile.setUserId(UUID.randomUUID());
|
||||||
|
profile.setGlobalRole(CoreUserGlobalRole.USER);
|
||||||
|
profile.setGlobalStatus(CoreUserGlobalStatus.ACTIVE);
|
||||||
|
|
||||||
|
return userDAO.insert(profile).compose(savedUser -> {
|
||||||
|
CredentialEntity cred = new CredentialEntity();
|
||||||
|
cred.setCredentialId(UUID.randomUUID());
|
||||||
|
cred.setUserId(savedUser.getUserId());
|
||||||
|
cred.setServiceId(this.serviceId);
|
||||||
|
cred.setUsername(username);
|
||||||
|
cred.setEmail(email);
|
||||||
|
cred.setPassword(PasswordHasher.hash(password));
|
||||||
|
cred.setStatus(1);
|
||||||
|
return credentialDAO.insert(cred).map(savedUser);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +1,35 @@
|
|||||||
package net.miarma.api.backlib.core.services;
|
package net.miarma.api.microservices.core.services;
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
|
||||||
import io.vertx.sqlclient.Pool;
|
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.OSType;
|
|
||||||
import net.miarma.api.backlib.exceptions.NotFoundException;
|
|
||||||
import net.miarma.api.backlib.exceptions.ValidationException;
|
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
|
||||||
import net.miarma.api.backlib.core.dao.FileDAO;
|
|
||||||
import net.miarma.api.backlib.core.entities.FileEntity;
|
|
||||||
import net.miarma.api.backlib.core.validators.FileValidator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
import net.miarma.api.backlib.config.OSType;
|
||||||
|
import net.miarma.api.backlib.exceptions.NotFoundException;
|
||||||
|
import net.miarma.api.backlib.exceptions.ValidationException;
|
||||||
|
import net.miarma.api.backlib.gson.GsonProvider;
|
||||||
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
|
import net.miarma.api.microservices.core.dao.FileDAO;
|
||||||
|
import net.miarma.api.microservices.core.entities.FileEntity;
|
||||||
|
import net.miarma.api.microservices.core.validators.FileValidator;
|
||||||
|
|
||||||
public class FileService {
|
public class FileService {
|
||||||
|
|
||||||
private final FileDAO fileDAO;
|
private final FileDAO fileDAO;
|
||||||
private final FileValidator fileValidator;
|
private final FileValidator fileValidator;
|
||||||
|
private final Gson GSON = GsonProvider.get();
|
||||||
|
private final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
|
|
||||||
public FileService(Pool pool) {
|
public FileService(Pool pool) {
|
||||||
this.fileDAO = new FileDAO(pool);
|
this.fileDAO = new FileDAO(pool);
|
||||||
@@ -32,7 +40,7 @@ public class FileService {
|
|||||||
return fileDAO.getAll(params);
|
return fileDAO.getAll(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<FileEntity> getById(Integer id) {
|
public Future<FileEntity> getById(UUID id) {
|
||||||
return fileDAO.getById(id).compose(file -> {
|
return fileDAO.getById(id).compose(file -> {
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
return Future.failedFuture(new NotFoundException("File not found with id: " + id));
|
return Future.failedFuture(new NotFoundException("File not found with id: " + id));
|
||||||
@@ -41,28 +49,28 @@ public class FileService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<List<FileEntity>> getUserFiles(Integer userId) {
|
public Future<List<FileEntity>> getUserFiles(UUID userId) {
|
||||||
return fileDAO.getUserFiles(userId);
|
return fileDAO.getUserFiles(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<FileEntity> create(FileEntity file, byte[] fileBinary) {
|
public Future<FileEntity> create(FileEntity file, byte[] fileBinary) {
|
||||||
return fileValidator.validate(file, fileBinary.length).compose(validation -> {
|
return fileValidator.validateAsync(file, fileBinary.length).compose(validation -> {
|
||||||
if (!validation.isValid()) {
|
if (!validation.isValid()) {
|
||||||
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
|
return Future.failedFuture(new ValidationException(GSON.toJson(validation.getErrors())));
|
||||||
}
|
}
|
||||||
|
|
||||||
String dir = ConfigManager.getInstance()
|
String dir = ConfigManager.getInstance()
|
||||||
.getFilesDir(file.getContext().toCtxString());
|
.getFilesDir(file.getContext().toCtxString());
|
||||||
|
|
||||||
String pathString = dir + file.getFile_name();
|
String pathString = dir + file.getFileName();
|
||||||
Path filePath = Paths.get(dir + file.getFile_name());
|
Path filePath = Paths.get(dir + file.getFileName());
|
||||||
file.setFile_path(ConfigManager.getOS() == OSType.WINDOWS ?
|
file.setFilePath(ConfigManager.getOS() == OSType.WINDOWS ?
|
||||||
pathString.replace("\\", "\\\\") : pathString);
|
pathString.replace("\\", "\\\\") : pathString);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Files.write(filePath, fileBinary);
|
Files.write(filePath, fileBinary);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Constants.LOGGER.error("Error writing file to disk: ", e);
|
LOGGER.error("Error writing file to disk: ", e);
|
||||||
return Future.failedFuture(e);
|
return Future.failedFuture(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,14 +78,14 @@ public class FileService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<FileEntity> downloadFile(Integer fileId) {
|
public Future<FileEntity> downloadFile(UUID fileId) {
|
||||||
return getById(fileId);
|
return getById(fileId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<FileEntity> update(FileEntity file) {
|
public Future<FileEntity> update(FileEntity file) {
|
||||||
return fileValidator.validate(file).compose(validation -> {
|
return fileValidator.validateAsync(file).compose(validation -> {
|
||||||
if (!validation.isValid()) {
|
if (!validation.isValid()) {
|
||||||
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
|
return Future.failedFuture(new ValidationException(GSON.toJson(validation.getErrors())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileDAO.update(file);
|
return fileDAO.update(file);
|
||||||
@@ -85,27 +93,27 @@ public class FileService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Future<FileEntity> upsert(FileEntity file) {
|
public Future<FileEntity> upsert(FileEntity file) {
|
||||||
return fileValidator.validate(file).compose(validation -> {
|
return fileValidator.validateAsync(file).compose(validation -> {
|
||||||
if (!validation.isValid()) {
|
if (!validation.isValid()) {
|
||||||
return Future.failedFuture(new ValidationException(Constants.GSON.toJson(validation.getErrors())));
|
return Future.failedFuture(new ValidationException(GSON.toJson(validation.getErrors())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileDAO.upsert(file, "file_id");
|
return fileDAO.upsert(file, "file_id");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Boolean> delete(Integer fileId) {
|
public Future<Boolean> delete(UUID fileId) {
|
||||||
return getById(fileId).compose(file -> {
|
return getById(fileId).compose(file -> {
|
||||||
String dir = ConfigManager.getInstance()
|
String dir = ConfigManager.getInstance()
|
||||||
.getFilesDir(file.getContext().toCtxString());
|
.getFilesDir(file.getContext().toCtxString());
|
||||||
|
|
||||||
String filePath = dir + file.getFile_name();
|
String filePath = dir + file.getFileName();
|
||||||
Path path = Paths.get(filePath);
|
Path path = Paths.get(filePath);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(path);
|
Files.deleteIfExists(path);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Constants.LOGGER.error("Error deleting file from disk: ", e);
|
LOGGER.error("Error deleting file from disk: ", e);
|
||||||
return Future.failedFuture(e);
|
return Future.failedFuture(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +126,7 @@ public class FileService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Boolean> exists(Integer fileId) {
|
public Future<Boolean> exists(UUID fileId) {
|
||||||
return fileDAO.exists(fileId);
|
return fileDAO.exists(fileId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package net.miarma.api.microservices.core.services;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import io.vertx.sqlclient.Pool;
|
||||||
|
import net.miarma.api.backlib.exceptions.NotFoundException;
|
||||||
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
|
import net.miarma.api.microservices.core.dao.UserDAO;
|
||||||
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalRole;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalStatus;
|
||||||
|
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
private final UserDAO userDAO;
|
||||||
|
|
||||||
|
public UserService(Pool pool) {
|
||||||
|
this.userDAO = new UserDAO(pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<List<UserEntity>> getAll(QueryParams params) {
|
||||||
|
return userDAO.getAll(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<UserEntity> getById(UUID id) {
|
||||||
|
return userDAO.getById(id).compose(user -> {
|
||||||
|
if (user == null) return Future.failedFuture(new NotFoundException("User not found"));
|
||||||
|
return Future.succeededFuture(user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<UserEntity> update(UserEntity user) {
|
||||||
|
return userDAO.update(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<UserEntity> changeRole(UUID userId, CoreUserGlobalRole newRole) {
|
||||||
|
return getById(userId).compose(user -> {
|
||||||
|
user.setGlobalRole(newRole);
|
||||||
|
return userDAO.update(user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<UserEntity> changeStatus(UUID userId, CoreUserGlobalStatus newStatus) {
|
||||||
|
return getById(userId).compose(user -> {
|
||||||
|
user.setGlobalStatus(newStatus);
|
||||||
|
return userDAO.update(user);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<Boolean> delete(UUID id) {
|
||||||
|
return userDAO.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package net.miarma.api.microservices.core.validators;
|
||||||
|
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import net.miarma.api.backlib.validation.ValidationResult;
|
||||||
|
import net.miarma.api.microservices.core.entities.FileEntity;
|
||||||
|
|
||||||
|
public class FileValidator {
|
||||||
|
|
||||||
|
private static final long MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||||
|
|
||||||
|
public Future<ValidationResult> validateAsync(FileEntity file, long size) {
|
||||||
|
ValidationResult result = validate(file);
|
||||||
|
|
||||||
|
if (size <= 0) {
|
||||||
|
result.addError("size", "File size must be greater than 0 bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size > MAX_FILE_SIZE) {
|
||||||
|
result.addError("size", "File size exceeds the 10 MB limit");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Future.succeededFuture(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future<ValidationResult> validateAsync(FileEntity file) {
|
||||||
|
ValidationResult result = validate(file);
|
||||||
|
return Future.succeededFuture(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidationResult validate(FileEntity file) {
|
||||||
|
ValidationResult result = new ValidationResult();
|
||||||
|
|
||||||
|
if (file == null) {
|
||||||
|
return result.addError("file", "File object cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.getFileName() == null || file.getFileName().isBlank()) {
|
||||||
|
result.addError("file_name", "File name is required");
|
||||||
|
} else if (file.getFileName().length() > 255) {
|
||||||
|
result.addError("file_name", "File name is too long (max 255 characters)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.getFilePath() == null || file.getFilePath().isBlank()) {
|
||||||
|
result.addError("file_path", "File path is required");
|
||||||
|
} else if (file.getFilePath().length() > 255) {
|
||||||
|
result.addError("file_path", "File path is too long (max 255 characters)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.getMimeType() == null || file.getMimeType().isBlank()) {
|
||||||
|
result.addError("mime_type", "MIME type is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.getContext() == null) {
|
||||||
|
result.addError("context", "File context is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.getUploadedBy() == null) {
|
||||||
|
result.addError("uploaded_by", "Uploader User ID is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package net.miarma.api.microservices.core.validators;
|
||||||
|
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
import net.miarma.api.backlib.validation.ValidationResult;
|
||||||
|
import net.miarma.api.microservices.core.entities.CredentialEntity;
|
||||||
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
|
|
||||||
|
public class UserValidator {
|
||||||
|
|
||||||
|
public Future<ValidationResult> validateAsync(UserEntity user, CredentialEntity creds) {
|
||||||
|
ValidationResult result = new ValidationResult();
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
return Future.succeededFuture(result.addError("user", "User profile cannot be null"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.getDisplayName() == null || user.getDisplayName().isBlank()) {
|
||||||
|
result.addError("display_name", "Display name is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creds == null) {
|
||||||
|
return Future.succeededFuture(result.addError("credentials", "Credentials are required"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creds.getUsername() == null || creds.getUsername().isBlank()) {
|
||||||
|
result.addError("username", "Username is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creds.getEmail() != null && !creds.getEmail().isBlank()) {
|
||||||
|
if (!creds.getEmail().matches("^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$")) {
|
||||||
|
result.addError("email", "Invalid email format");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.addError("email", "Email is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (creds.getPassword() == null || creds.getPassword().isBlank()) {
|
||||||
|
result.addError("password", "Password is required");
|
||||||
|
} else if (creds.getPassword().length() < 6) {
|
||||||
|
result.addError("password", "Password must be at least 6 characters long");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Future.succeededFuture(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,196 +1,123 @@
|
|||||||
package net.miarma.api.microservices.core.verticles;
|
package net.miarma.api.microservices.core.verticles;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.UUID;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
import io.vertx.core.AbstractVerticle;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.Constants;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserGlobalStatus;
|
|
||||||
import net.miarma.api.backlib.Constants.CoreUserRole;
|
|
||||||
import net.miarma.api.backlib.core.entities.UserEntity;
|
|
||||||
import net.miarma.api.backlib.core.services.FileService;
|
|
||||||
import net.miarma.api.backlib.core.services.UserService;
|
|
||||||
import net.miarma.api.backlib.db.DatabaseProvider;
|
import net.miarma.api.backlib.db.DatabaseProvider;
|
||||||
import net.miarma.api.backlib.util.EventBusUtil;
|
import net.miarma.api.backlib.util.EventBusUtil;
|
||||||
import net.miarma.api.backlib.util.RouterUtil;
|
import net.miarma.api.backlib.util.RouterUtil;
|
||||||
|
import net.miarma.api.microservices.core.entities.UserEntity;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalRole;
|
||||||
|
import net.miarma.api.microservices.core.enums.CoreUserGlobalStatus;
|
||||||
import net.miarma.api.microservices.core.routing.CoreDataRouter;
|
import net.miarma.api.microservices.core.routing.CoreDataRouter;
|
||||||
|
import net.miarma.api.microservices.core.routing.CoreEndpoints;
|
||||||
|
import net.miarma.api.microservices.core.services.AuthService;
|
||||||
|
import net.miarma.api.microservices.core.services.FileService;
|
||||||
|
import net.miarma.api.microservices.core.services.UserService;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class CoreDataVerticle extends AbstractVerticle {
|
public class CoreDataVerticle extends AbstractVerticle {
|
||||||
private ConfigManager configManager;
|
private ConfigManager configManager;
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
private FileService fileService;
|
private FileService fileService;
|
||||||
|
private AuthService authService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Promise<Void> startPromise) {
|
public void start(Promise<Void> startPromise) {
|
||||||
configManager = ConfigManager.getInstance();
|
configManager = ConfigManager.getInstance();
|
||||||
Pool pool = DatabaseProvider.createPool(vertx, configManager);
|
Pool pool = DatabaseProvider.createPool(vertx, configManager);
|
||||||
|
|
||||||
userService = new UserService(pool);
|
userService = new UserService(pool);
|
||||||
fileService = new FileService(pool);
|
fileService = new FileService(pool);
|
||||||
|
authService = new AuthService(pool, 0);
|
||||||
|
|
||||||
Router router = Router.router(vertx);
|
Router router = Router.router(vertx);
|
||||||
RouterUtil.attachLogger(router);
|
RouterUtil.attachLogger(router);
|
||||||
CoreDataRouter.mount(router, vertx, pool);
|
CoreDataRouter.mount(router, vertx, pool);
|
||||||
|
|
||||||
registerLogicVerticleConsumer();
|
registerLogicVerticleConsumer();
|
||||||
|
|
||||||
vertx.createHttpServer()
|
vertx.createHttpServer()
|
||||||
.requestHandler(router)
|
.requestHandler(router)
|
||||||
.listen(configManager.getIntProperty("sso.data.port"), res -> {
|
.listen(configManager.getIntProperty("core.data.port"), res -> {
|
||||||
if (res.succeeded()) startPromise.complete();
|
if (res.succeeded()) startPromise.complete();
|
||||||
else startPromise.fail(res.cause());
|
else startPromise.fail(res.cause());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerLogicVerticleConsumer() {
|
private void registerLogicVerticleConsumer() {
|
||||||
vertx.eventBus().consumer(Constants.AUTH_EVENT_BUS, message -> {
|
String authAddress = configManager.getStringProperty("eventbus.auth.address");
|
||||||
|
|
||||||
|
vertx.eventBus().consumer(authAddress, message -> {
|
||||||
JsonObject body = (JsonObject) message.body();
|
JsonObject body = (JsonObject) message.body();
|
||||||
String action = body.getString("action");
|
String action = body.getString("action");
|
||||||
|
|
||||||
|
try {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "login" -> {
|
case "login" -> {
|
||||||
String email = body.getString("email");
|
authService.login(
|
||||||
String userName = body.getString("userName");
|
body.getString("login"),
|
||||||
String password = body.getString("password");
|
body.getString("password"),
|
||||||
boolean keepLoggedIn = body.getBoolean("keepLoggedIn", false);
|
body.getBoolean("keepLoggedIn", false)
|
||||||
|
).onSuccess(message::reply).onFailure(EventBusUtil.fail(message));
|
||||||
userService.login(email != null ? email : userName, password, keepLoggedIn)
|
|
||||||
.onSuccess(message::reply)
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "register" -> {
|
case "register" -> {
|
||||||
UserEntity user = new UserEntity();
|
UserEntity profile = new UserEntity();
|
||||||
user.setUser_name(body.getString("userName"));
|
profile.setDisplayName(body.getString("displayName"));
|
||||||
user.setEmail(body.getString("email"));
|
|
||||||
user.setDisplay_name(body.getString("displayName"));
|
|
||||||
user.setPassword(body.getString("password"));
|
|
||||||
|
|
||||||
userService.register(user)
|
authService.register(
|
||||||
|
profile,
|
||||||
|
body.getString("username"),
|
||||||
|
body.getString("email"),
|
||||||
|
body.getString("password")
|
||||||
|
).onSuccess(user -> message.reply(JsonObject.mapFrom(user)))
|
||||||
|
.onFailure(EventBusUtil.fail(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "getInfo", "getById", "getUserById" -> {
|
||||||
|
userService.getById(UUID.fromString(body.getString("userId")))
|
||||||
|
.onSuccess(user -> message.reply(JsonObject.mapFrom(user)))
|
||||||
|
.onFailure(EventBusUtil.fail(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "updateStatus" -> {
|
||||||
|
userService.changeStatus(
|
||||||
|
UUID.fromString(body.getString("userId")),
|
||||||
|
CoreUserGlobalStatus.fromInt(body.getInteger("status"))
|
||||||
|
).onSuccess(res -> message.reply(new JsonObject().put("message", "Status updated")))
|
||||||
|
.onFailure(EventBusUtil.fail(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "updateRole" -> {
|
||||||
|
userService.changeRole(
|
||||||
|
UUID.fromString(body.getString("userId")),
|
||||||
|
CoreUserGlobalRole.fromInt(body.getInteger("role"))
|
||||||
|
).onSuccess(res -> message.reply(new JsonObject().put("message", "Role updated")))
|
||||||
|
.onFailure(EventBusUtil.fail(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
case "getUserFiles" -> {
|
||||||
|
fileService.getUserFiles(UUID.fromString(body.getString("userId")))
|
||||||
.onSuccess(message::reply)
|
.onSuccess(message::reply)
|
||||||
.onFailure(EventBusUtil.fail(message));
|
.onFailure(EventBusUtil.fail(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "changePassword" -> {
|
case "downloadFile" -> {
|
||||||
Integer userId = body.getInteger("userId");
|
fileService.getById(UUID.fromString(body.getString("fileId")))
|
||||||
String newPassword = body.getString("newPassword");
|
|
||||||
|
|
||||||
userService.changePassword(userId, newPassword)
|
|
||||||
.onSuccess(user -> {
|
|
||||||
String userJson = Constants.GSON.toJson(user);
|
|
||||||
message.reply(new JsonObject(userJson));
|
|
||||||
})
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
case "validateToken" -> {
|
|
||||||
String token = body.getString("token");
|
|
||||||
|
|
||||||
userService.validateToken(token)
|
|
||||||
.onSuccess(message::reply)
|
.onSuccess(message::reply)
|
||||||
.onFailure(EventBusUtil.fail(message));
|
.onFailure(EventBusUtil.fail(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
case "getInfo", "getById" -> {
|
default -> message.fail(404, "Action not found: " + action);
|
||||||
Integer userId = body.getInteger("userId");
|
|
||||||
|
|
||||||
userService.getById(userId)
|
|
||||||
.onSuccess(message::reply)
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
case "userExists" -> {
|
message.fail(400, "Invalid data format or UUID: " + e.getMessage());
|
||||||
Integer userId = body.getInteger("userId");
|
|
||||||
|
|
||||||
userService.getById(userId)
|
|
||||||
.onSuccess(user -> {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("user_id", userId);
|
|
||||||
result.put("exists", user != null);
|
|
||||||
message.reply(result);
|
|
||||||
})
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
case "getByEmail" -> userService.getByEmail(body.getString("email"))
|
|
||||||
.onSuccess(message::reply)
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "getByUserName" -> userService.getByUserName(body.getString("userName"))
|
|
||||||
.onSuccess(message::reply)
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "getStatus" -> userService.getById(body.getInteger("userId"))
|
|
||||||
.onSuccess(user -> {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("user_id", user.getUser_id());
|
|
||||||
result.put("status", user.getGlobal_status());
|
|
||||||
message.reply(result);
|
|
||||||
})
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "getRole" -> userService.getById(body.getInteger("userId"))
|
|
||||||
.onSuccess(user -> {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("user_id", user.getUser_id());
|
|
||||||
result.put("role", user.getGlobal_role());
|
|
||||||
message.reply(result);
|
|
||||||
})
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "getAvatar" -> userService.getById(body.getInteger("userId"))
|
|
||||||
.onSuccess(user -> {
|
|
||||||
Map<String, Object> result = new HashMap<>();
|
|
||||||
result.put("user_id", user.getUser_id());
|
|
||||||
result.put("avatar", user.getAvatar());
|
|
||||||
message.reply(result);
|
|
||||||
})
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "updateStatus" -> userService.updateStatus(
|
|
||||||
body.getInteger("userId"),
|
|
||||||
CoreUserGlobalStatus.fromInt(body.getInteger("status")))
|
|
||||||
.onSuccess(res -> message.reply("Status updated successfully"))
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "updateRole" -> userService.updateRole(
|
|
||||||
body.getInteger("userId"),
|
|
||||||
CoreUserRole.fromInt(body.getInteger("role")))
|
|
||||||
.onSuccess(res -> message.reply("Role updated successfully"))
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "getUserFiles" -> fileService.getUserFiles(body.getInteger("userId"))
|
|
||||||
.onSuccess(message::reply)
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "downloadFile" -> fileService.downloadFile(body.getInteger("fileId"))
|
|
||||||
.onSuccess(message::reply)
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "getUserById" -> userService.getById(body.getInteger("userId"))
|
|
||||||
.onSuccess(user -> {
|
|
||||||
String userJson = Constants.GSON.toJson(user);
|
|
||||||
message.reply(new JsonObject(userJson));
|
|
||||||
})
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
|
|
||||||
case "loginValidate" -> {
|
|
||||||
Integer userId = body.getInteger("userId");
|
|
||||||
String password = body.getString("password");
|
|
||||||
|
|
||||||
userService.loginValidate(userId, password)
|
|
||||||
.onSuccess(user -> {
|
|
||||||
String userJson = Constants.GSON.toJson(user);
|
|
||||||
message.reply(new JsonObject(userJson));
|
|
||||||
})
|
|
||||||
.onFailure(EventBusUtil.fail(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
default -> EventBusUtil.fail(message);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import io.vertx.core.Promise;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.db.DatabaseProvider;
|
import net.miarma.api.backlib.db.DatabaseProvider;
|
||||||
import net.miarma.api.backlib.util.RouterUtil;
|
import net.miarma.api.backlib.util.RouterUtil;
|
||||||
import net.miarma.api.microservices.core.routing.CoreLogicRouter;
|
import net.miarma.api.microservices.core.routing.CoreLogicRouter;
|
||||||
@@ -24,7 +24,7 @@ public class CoreLogicVerticle extends AbstractVerticle {
|
|||||||
|
|
||||||
vertx.createHttpServer()
|
vertx.createHttpServer()
|
||||||
.requestHandler(router)
|
.requestHandler(router)
|
||||||
.listen(configManager.getIntProperty("sso.logic.port"), res -> {
|
.listen(configManager.getIntProperty("core.logic.port"), res -> {
|
||||||
if (res.succeeded()) startPromise.complete();
|
if (res.succeeded()) startPromise.complete();
|
||||||
else startPromise.fail(res.cause());
|
else startPromise.fail(res.cause());
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
package net.miarma.api.microservices.core.verticles;
|
package net.miarma.api.microservices.core.verticles;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
import io.vertx.core.AbstractVerticle;
|
||||||
import io.vertx.core.DeploymentOptions;
|
import io.vertx.core.DeploymentOptions;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.core.ThreadingModel;
|
import io.vertx.core.ThreadingModel;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.log.LogAccumulator;
|
||||||
import net.miarma.api.backlib.LogAccumulator;
|
import net.miarma.api.backlib.log.LoggerProvider;
|
||||||
import net.miarma.api.backlib.util.DeploymentUtil;
|
import net.miarma.api.backlib.util.DeploymentUtil;
|
||||||
|
|
||||||
public class CoreMainVerticle extends AbstractVerticle {
|
public class CoreMainVerticle extends AbstractVerticle {
|
||||||
|
|
||||||
|
private final Logger LOGGER = LoggerProvider.getLogger();
|
||||||
private ConfigManager configManager;
|
private ConfigManager configManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -20,7 +23,7 @@ public class CoreMainVerticle extends AbstractVerticle {
|
|||||||
deployVerticles();
|
deployVerticles();
|
||||||
startPromise.complete();
|
startPromise.complete();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Constants.LOGGER.error(DeploymentUtil.failMessage(CoreMainVerticle.class, e));
|
LOGGER.error(DeploymentUtil.failMessage(CoreMainVerticle.class, e));
|
||||||
startPromise.fail(e);
|
startPromise.fail(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,7 +38,7 @@ public class CoreMainVerticle extends AbstractVerticle {
|
|||||||
DeploymentUtil.successMessage(CoreDataVerticle.class),
|
DeploymentUtil.successMessage(CoreDataVerticle.class),
|
||||||
DeploymentUtil.apiUrlMessage(
|
DeploymentUtil.apiUrlMessage(
|
||||||
configManager.getHost(),
|
configManager.getHost(),
|
||||||
configManager.getIntProperty("sso.data.port")
|
configManager.getIntProperty("core.data.port")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
LogAccumulator.add(message);
|
LogAccumulator.add(message);
|
||||||
@@ -50,7 +53,7 @@ public class CoreMainVerticle extends AbstractVerticle {
|
|||||||
DeploymentUtil.successMessage(CoreLogicVerticle.class),
|
DeploymentUtil.successMessage(CoreLogicVerticle.class),
|
||||||
DeploymentUtil.apiUrlMessage(
|
DeploymentUtil.apiUrlMessage(
|
||||||
configManager.getHost(),
|
configManager.getHost(),
|
||||||
configManager.getIntProperty("sso.logic.port")
|
configManager.getIntProperty("core.logic.port")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
LogAccumulator.add(message);
|
LogAccumulator.add(message);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>huertos</artifactId>
|
<artifactId>huertos</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>23</maven.compiler.source>
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
@@ -20,36 +20,8 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>backlib</artifactId>
|
<artifactId>backlib</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>ME-Huertos</finalName>
|
|
||||||
<plugins>
|
|
||||||
<!-- Maven Shade Plugin -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.5.3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<transformers>
|
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
|
||||||
<mainClass>net.miarma.api.microservices.huertos.HuertosMainVerticle</mainClass>
|
|
||||||
</transformer>
|
|
||||||
</transformers>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.miarma.api.microservices.huertos.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum HuertosAnnouncementPriority implements IValuableEnum {
|
||||||
|
LOW(0),
|
||||||
|
MEDIUM(1),
|
||||||
|
HIGH(2);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
HuertosAnnouncementPriority(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HuertosAnnouncementPriority fromInt(int i) {
|
||||||
|
for (HuertosAnnouncementPriority priority : values()) {
|
||||||
|
if (priority.value == i) return priority;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid HuertosAnnouncementPriority value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.miarma.api.microservices.huertos.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum HuertosPaymentFrequency implements IValuableEnum {
|
||||||
|
BIYEARLY(0),
|
||||||
|
YEARLY(1);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
HuertosPaymentFrequency(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HuertosPaymentFrequency fromInt(int i) {
|
||||||
|
for (HuertosPaymentFrequency frequency : values()) {
|
||||||
|
if (frequency.value == i) return frequency;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid HuertoPaymentFrequency value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.miarma.api.microservices.huertos.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum HuertosPaymentType implements IValuableEnum {
|
||||||
|
BANK(0),
|
||||||
|
CASH(1);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
HuertosPaymentType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HuertosPaymentType fromInt(int i) {
|
||||||
|
for (HuertosPaymentType type : values()) {
|
||||||
|
if (type.value == i) return type;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid HuertoPaymentType value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.miarma.api.microservices.huertos.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum HuertosRequestStatus implements IValuableEnum {
|
||||||
|
PENDING(0),
|
||||||
|
APPROVED(1),
|
||||||
|
REJECTED(2);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
HuertosRequestStatus(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HuertosRequestStatus fromInt(int i) {
|
||||||
|
for (HuertosRequestStatus status : values()) {
|
||||||
|
if (status.value == i) return status;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid HuertoRequestStatus value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package net.miarma.api.microservices.huertos.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum HuertosRequestType implements IValuableEnum {
|
||||||
|
REGISTER(0),
|
||||||
|
UNREGISTER(1),
|
||||||
|
ADD_COLLABORATOR(2),
|
||||||
|
REMOVE_COLLABORATOR(3),
|
||||||
|
ADD_GREENHOUSE(4),
|
||||||
|
REMOVE_GREENHOUSE(5);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
HuertosRequestType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HuertosRequestType fromInt(int i) {
|
||||||
|
for (HuertosRequestType type : values()) {
|
||||||
|
if (type.value == i) return type;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid HuertoRequestType value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.miarma.api.microservices.huertos.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IUserRole;
|
||||||
|
|
||||||
|
public enum HuertosUserRole implements IUserRole {
|
||||||
|
USER(0),
|
||||||
|
ADMIN(1),
|
||||||
|
DEV(2);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
HuertosUserRole(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HuertosUserRole fromInt(int i) {
|
||||||
|
for (HuertosUserRole role : values()) {
|
||||||
|
if (role.value == i) return role;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid HuertosUserRole value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package net.miarma.api.microservices.huertos.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum HuertosUserType implements IValuableEnum {
|
||||||
|
WAIT_LIST(0),
|
||||||
|
MEMBER(1),
|
||||||
|
WITH_GREENHOUSE(2),
|
||||||
|
COLLABORATOR(3),
|
||||||
|
DEVELOPER(5),
|
||||||
|
SUBSIDY(4);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
HuertosUserType(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HuertosUserType fromInt(int i) {
|
||||||
|
for (HuertosUserType type : values()) {
|
||||||
|
if (type.value == i) return type;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid HuertosUserType value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,8 +10,8 @@ import io.vertx.core.WorkerExecutor;
|
|||||||
import io.vertx.core.json.Json;
|
import io.vertx.core.json.Json;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
import net.miarma.api.backlib.security.JWTManager;
|
import net.miarma.api.backlib.security.JWTManager;
|
||||||
import net.miarma.api.microservices.huertos.entities.MemberEntity;
|
import net.miarma.api.microservices.huertos.entities.MemberEntity;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import jakarta.mail.Session;
|
|||||||
import jakarta.mail.Store;
|
import jakarta.mail.Store;
|
||||||
import jakarta.mail.internet.MimeMessage;
|
import jakarta.mail.internet.MimeMessage;
|
||||||
import jakarta.mail.internet.MimeUtility;
|
import jakarta.mail.internet.MimeUtility;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
|
||||||
public class ImapReader {
|
public class ImapReader {
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import jakarta.mail.Session;
|
|||||||
import jakarta.mail.Store;
|
import jakarta.mail.Store;
|
||||||
import jakarta.mail.internet.InternetAddress;
|
import jakarta.mail.internet.InternetAddress;
|
||||||
import jakarta.mail.internet.MimeMessage;
|
import jakarta.mail.internet.MimeMessage;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
|
||||||
public class MailManager {
|
public class MailManager {
|
||||||
private final Vertx vertx;
|
private final Vertx vertx;
|
||||||
@@ -31,6 +31,9 @@ public class MailManager {
|
|||||||
private final int smtpPort;
|
private final int smtpPort;
|
||||||
private final Map<String, MailClient> clientCache = new ConcurrentHashMap<>();
|
private final Map<String, MailClient> clientCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static final List<String> HUERTOS_ALLOWED_MAIL_FOLDERS =
|
||||||
|
List.of("INBOX", "Drafts", "Sent", "Spam", "Trash");
|
||||||
|
|
||||||
public MailManager(Vertx vertx) {
|
public MailManager(Vertx vertx) {
|
||||||
this.vertx = vertx;
|
this.vertx = vertx;
|
||||||
this.smtpHost = ConfigManager.getInstance().getStringProperty("smtp.server");
|
this.smtpHost = ConfigManager.getInstance().getStringProperty("smtp.server");
|
||||||
|
|||||||
@@ -33,44 +33,44 @@ public class HuertosDataRouter {
|
|||||||
|
|
||||||
router.get(HuertosEndpoints.ANNOUNCES).handler(authGuard.check()).handler(hAnnounceData::getAll);
|
router.get(HuertosEndpoints.ANNOUNCES).handler(authGuard.check()).handler(hAnnounceData::getAll);
|
||||||
router.get(HuertosEndpoints.ANNOUNCE).handler(authGuard.check()).handler(hAnnounceData::getById);
|
router.get(HuertosEndpoints.ANNOUNCE).handler(authGuard.check()).handler(hAnnounceData::getById);
|
||||||
router.post(HuertosEndpoints.ANNOUNCES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hAnnounceData::create);
|
router.post(HuertosEndpoints.ANNOUNCES).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hAnnounceData::create);
|
||||||
router.put(HuertosEndpoints.ANNOUNCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hAnnounceData::update);
|
router.put(HuertosEndpoints.ANNOUNCE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hAnnounceData::update);
|
||||||
router.delete(HuertosEndpoints.ANNOUNCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hAnnounceData::delete);
|
router.delete(HuertosEndpoints.ANNOUNCE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hAnnounceData::delete);
|
||||||
|
|
||||||
router.get(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hBalanceData::getBalance);
|
router.get(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hBalanceData::getBalance);
|
||||||
router.post(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hBalanceData::update);
|
router.post(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hBalanceData::update);
|
||||||
router.delete(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hBalanceData::create);
|
router.delete(HuertosEndpoints.BALANCE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hBalanceData::create);
|
||||||
|
|
||||||
router.get(HuertosEndpoints.EXPENSES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::getAll);
|
router.get(HuertosEndpoints.EXPENSES).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hExpenseData::getAll);
|
||||||
router.get(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::getById);
|
router.get(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hExpenseData::getById);
|
||||||
router.post(HuertosEndpoints.EXPENSES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::create);
|
router.post(HuertosEndpoints.EXPENSES).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hExpenseData::create);
|
||||||
router.put(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::update);
|
router.put(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hExpenseData::update);
|
||||||
router.delete(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hExpenseData::delete);
|
router.delete(HuertosEndpoints.EXPENSE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hExpenseData::delete);
|
||||||
|
|
||||||
router.get(HuertosEndpoints.INCOMES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::getAll);
|
router.get(HuertosEndpoints.INCOMES).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hIncomeData::getAll);
|
||||||
router.get(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::getById);
|
router.get(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hIncomeData::getById);
|
||||||
router.post(HuertosEndpoints.INCOMES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::create);
|
router.post(HuertosEndpoints.INCOMES).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hIncomeData::create);
|
||||||
router.put(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::update);
|
router.put(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hIncomeData::update);
|
||||||
router.delete(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::delete);
|
router.delete(HuertosEndpoints.INCOME).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hIncomeData::delete);
|
||||||
router.get(HuertosEndpoints.INCOMES_WITH_NAMES).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hIncomeData::getIncomesWithNames);
|
router.get(HuertosEndpoints.INCOMES_WITH_NAMES).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hIncomeData::getIncomesWithNames);
|
||||||
|
|
||||||
router.get(HuertosEndpoints.MEMBERS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::getAll);
|
router.get(HuertosEndpoints.MEMBERS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberData::getAll);
|
||||||
router.get(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::getById);
|
router.get(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberData::getById);
|
||||||
router.post(HuertosEndpoints.MEMBERS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::create);
|
router.post(HuertosEndpoints.MEMBERS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberData::create);
|
||||||
router.put(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::update);
|
router.put(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberData::update);
|
||||||
router.delete(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hMemberData::delete);
|
router.delete(HuertosEndpoints.MEMBER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberData::delete);
|
||||||
|
|
||||||
router.get(HuertosEndpoints.PRE_USERS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::getAll);
|
router.get(HuertosEndpoints.PRE_USERS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hPreUserData::getAll);
|
||||||
router.get(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::getById);
|
router.get(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hPreUserData::getById);
|
||||||
router.post(HuertosEndpoints.PRE_USERS).handler(hPreUserData::create);
|
router.post(HuertosEndpoints.PRE_USERS).handler(hPreUserData::create);
|
||||||
router.put(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::update);
|
router.put(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hPreUserData::update);
|
||||||
router.delete(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hPreUserData::delete);
|
router.delete(HuertosEndpoints.PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hPreUserData::delete);
|
||||||
|
|
||||||
router.get(HuertosEndpoints.REQUESTS).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::getAll);
|
router.get(HuertosEndpoints.REQUESTS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestData::getAll);
|
||||||
router.get(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::getById);
|
router.get(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestData::getById);
|
||||||
router.post(HuertosEndpoints.REQUESTS).handler(hRequestData::create);
|
router.post(HuertosEndpoints.REQUESTS).handler(hRequestData::create);
|
||||||
router.put(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::update);
|
router.put(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestData::update);
|
||||||
router.delete(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN)).handler(hRequestData::delete);
|
router.delete(HuertosEndpoints.REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestData::delete);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import io.vertx.core.Vertx;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.util.RouterUtil;
|
import net.miarma.api.backlib.Constants.HuertosUserRole;
|
||||||
import net.miarma.api.microservices.huertos.handlers.BalanceLogicHandler;
|
import net.miarma.api.microservices.huertos.handlers.BalanceLogicHandler;
|
||||||
import net.miarma.api.microservices.huertos.handlers.IncomeLogicHandler;
|
import net.miarma.api.microservices.huertos.handlers.IncomeLogicHandler;
|
||||||
import net.miarma.api.microservices.huertos.handlers.MailHandler;
|
import net.miarma.api.microservices.huertos.handlers.MailHandler;
|
||||||
@@ -26,34 +26,34 @@ public class HuertosLogicRouter {
|
|||||||
router.route().handler(BodyHandler.create());
|
router.route().handler(BodyHandler.create());
|
||||||
|
|
||||||
router.post(HuertosEndpoints.LOGIN).handler(hMemberLogic::login);
|
router.post(HuertosEndpoints.LOGIN).handler(hMemberLogic::login);
|
||||||
router.get(HuertosEndpoints.MEMBER_BY_NUMBER).handler(authGuard.check()).handler(hMemberLogic::getByMemberNumber);
|
router.get(HuertosEndpoints.MEMBER_BY_NUMBER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::getByMemberNumber);
|
||||||
router.get(HuertosEndpoints.MEMBER_BY_PLOT).handler(authGuard.check()).handler(hMemberLogic::getByPlotNumber);
|
router.get(HuertosEndpoints.MEMBER_BY_PLOT).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::getByPlotNumber);
|
||||||
router.get(HuertosEndpoints.MEMBER_BY_DNI).handler(authGuard.check()).handler(hMemberLogic::getByDni);
|
router.get(HuertosEndpoints.MEMBER_BY_DNI).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::getByDni);
|
||||||
router.get(HuertosEndpoints.MEMBER_PAYMENTS).handler(authGuard.check()).handler(hMemberLogic::getUserPayments);
|
router.get(HuertosEndpoints.MEMBER_PAYMENTS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::getUserPayments);
|
||||||
router.get(HuertosEndpoints.MEMBER_HAS_PAID).handler(authGuard.check()).handler(hMemberLogic::hasPaid);
|
router.get(HuertosEndpoints.MEMBER_HAS_PAID).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::hasPaid);
|
||||||
router.get(HuertosEndpoints.MEMBER_WAITLIST).handler(authGuard.check()).handler(hMemberLogic::getWaitlist);
|
router.get(HuertosEndpoints.MEMBER_WAITLIST).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::getWaitlist);
|
||||||
router.get(HuertosEndpoints.MEMBER_LIMITED_WAITLIST).handler(hMemberLogic::getLimitedWaitlist);
|
router.get(HuertosEndpoints.MEMBER_LIMITED_WAITLIST).handler(hMemberLogic::getLimitedWaitlist);
|
||||||
router.get(HuertosEndpoints.LAST_MEMBER_NUMBER).handler(hMemberLogic::getLastMemberNumber);
|
router.get(HuertosEndpoints.LAST_MEMBER_NUMBER).handler(hMemberLogic::getLastMemberNumber);
|
||||||
router.get(HuertosEndpoints.BALANCE_WITH_TOTALS).handler(authGuard.check()).handler(hBalanceLogic::getBalanceWithTotals);
|
router.get(HuertosEndpoints.BALANCE_WITH_TOTALS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hBalanceLogic::getBalanceWithTotals);
|
||||||
router.get(HuertosEndpoints.REQUESTS_WITH_PRE_USERS).handler(authGuard.check()).handler(hRequestLogic::getRequestsWithPreUsers);
|
router.get(HuertosEndpoints.REQUESTS_WITH_PRE_USERS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestLogic::getRequestsWithPreUsers);
|
||||||
router.get(HuertosEndpoints.REQUEST_WITH_PRE_USER).handler(authGuard.check()).handler(hRequestLogic::getRequestWithPreUser);
|
router.get(HuertosEndpoints.REQUEST_WITH_PRE_USER).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestLogic::getRequestWithPreUser);
|
||||||
router.get(HuertosEndpoints.MEMBER_PROFILE).handler(hMemberLogic::getProfile);
|
router.get(HuertosEndpoints.MEMBER_PROFILE).handler(hMemberLogic::getProfile);
|
||||||
router.get(HuertosEndpoints.REQUEST_COUNT).handler(authGuard.check()).handler(hRequestLogic::getRequestCount);
|
router.get(HuertosEndpoints.REQUEST_COUNT).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestLogic::getRequestCount);
|
||||||
router.get(HuertosEndpoints.MY_INCOMES).handler(authGuard.check()).handler(hIncomeLogic::getMyIncomes);
|
router.get(HuertosEndpoints.MY_INCOMES).handler(authGuard.check()).handler(hIncomeLogic::getMyIncomes);
|
||||||
router.get(HuertosEndpoints.MY_REQUESTS).handler(authGuard.check()).handler(hRequestLogic::getMyRequests);
|
router.get(HuertosEndpoints.MY_REQUESTS).handler(authGuard.check()).handler(hRequestLogic::getMyRequests);
|
||||||
router.put(HuertosEndpoints.ACCEPT_REQUEST).handler(authGuard.check()).handler(hRequestLogic::acceptRequest);
|
router.put(HuertosEndpoints.ACCEPT_REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestLogic::acceptRequest);
|
||||||
router.put(HuertosEndpoints.REJECT_REQUEST).handler(authGuard.check()).handler(hRequestLogic::rejectRequest);
|
router.put(HuertosEndpoints.REJECT_REQUEST).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hRequestLogic::rejectRequest);
|
||||||
router.put(HuertosEndpoints.CHANGE_MEMBER_STATUS).handler(authGuard.check()).handler(hMemberLogic::changeMemberStatus);
|
router.put(HuertosEndpoints.CHANGE_MEMBER_STATUS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::changeMemberStatus);
|
||||||
router.put(HuertosEndpoints.CHANGE_MEMBER_TYPE).handler(authGuard.check()).handler(hMemberLogic::changeMemberType);
|
router.put(HuertosEndpoints.CHANGE_MEMBER_TYPE).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMemberLogic::changeMemberType);
|
||||||
router.get(HuertosEndpoints.MEMBER_HAS_COLLABORATOR).handler(authGuard.check()).handler(hMemberLogic::hasCollaborator);
|
router.get(HuertosEndpoints.MEMBER_HAS_COLLABORATOR).handler(authGuard.check()).handler(hMemberLogic::hasCollaborator);
|
||||||
router.get(HuertosEndpoints.MEMBER_HAS_COLLABORATOR_REQUEST).handler(authGuard.check()).handler(hMemberLogic::hasCollaboratorRequest);
|
router.get(HuertosEndpoints.MEMBER_HAS_COLLABORATOR_REQUEST).handler(authGuard.check()).handler(hMemberLogic::hasCollaboratorRequest);
|
||||||
router.get(HuertosEndpoints.MEMBER_HAS_GREENHOUSE).handler(authGuard.check()).handler(hMemberLogic::hasGreenHouse);
|
router.get(HuertosEndpoints.MEMBER_HAS_GREENHOUSE).handler(authGuard.check()).handler(hMemberLogic::hasGreenHouse);
|
||||||
router.get(HuertosEndpoints.MEMBER_HAS_GREENHOUSE_REQUEST).handler(authGuard.check()).handler(hMemberLogic::hasGreenHouseRequest);
|
router.get(HuertosEndpoints.MEMBER_HAS_GREENHOUSE_REQUEST).handler(authGuard.check()).handler(hMemberLogic::hasGreenHouseRequest);
|
||||||
router.post(HuertosEndpoints.PRE_USER_VALIDATE).handler(hMemberLogic::validatePreUser);
|
router.post(HuertosEndpoints.PRE_USER_VALIDATE).handler(hMemberLogic::validatePreUser);
|
||||||
|
|
||||||
router.get(HuertosEndpoints.MAILS).handler(hMail::getFolder);
|
router.get(HuertosEndpoints.MAILS).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMail::getFolder);
|
||||||
router.get(HuertosEndpoints.MAIL).handler(hMail::getMail);
|
router.get(HuertosEndpoints.MAIL).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMail::getMail);
|
||||||
router.post(HuertosEndpoints.SEND_MAIL).handler(hMail::sendMail);
|
router.post(HuertosEndpoints.SEND_MAIL).handler(authGuard.check(HuertosUserRole.ADMIN, HuertosUserRole.DEV)).handler(hMail::sendMail);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,18 @@ package net.miarma.api.microservices.huertos.routing.middlewares;
|
|||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.miarma.api.backlib.Constants.HuertosUserRole;
|
import net.miarma.api.backlib.Constants.HuertosUserRole;
|
||||||
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
import net.miarma.api.backlib.middlewares.AbstractAuthGuard;
|
import net.miarma.api.backlib.middlewares.AbstractAuthGuard;
|
||||||
|
import net.miarma.api.backlib.security.JWTManager;
|
||||||
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
import net.miarma.api.microservices.huertos.entities.MemberEntity;
|
import net.miarma.api.microservices.huertos.entities.MemberEntity;
|
||||||
import net.miarma.api.microservices.huertos.services.MemberService;
|
import net.miarma.api.microservices.huertos.services.MemberService;
|
||||||
|
|
||||||
public class HuertosAuthGuard extends AbstractAuthGuard<MemberEntity, HuertosUserRole> {
|
public class HuertosAuthGuard extends AbstractAuthGuard<MemberEntity, HuertosUserRole> {
|
||||||
|
|
||||||
private final MemberService memberService;
|
private final MemberService memberService;
|
||||||
|
|
||||||
public HuertosAuthGuard(MemberService memberService) {
|
public HuertosAuthGuard(MemberService memberService) {
|
||||||
@@ -29,7 +34,43 @@ public class HuertosAuthGuard extends AbstractAuthGuard<MemberEntity, HuertosUse
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasPermission(MemberEntity user, HuertosUserRole role) {
|
protected boolean hasPermission(MemberEntity member, HuertosUserRole userRole) {
|
||||||
return user.getRole() == HuertosUserRole.ADMIN;
|
return member.getRole() == HuertosUserRole.ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Handler<RoutingContext> check(HuertosUserRole... allowedRoles) {
|
||||||
|
return ctx -> {
|
||||||
|
String token = extractToken(ctx);
|
||||||
|
if (token == null || !JWTManager.getInstance().isValid(token)) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, "Invalid or missing token");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int userId = JWTManager.getInstance().extractUserId(token);
|
||||||
|
|
||||||
|
getUserEntity(userId, ctx, member -> {
|
||||||
|
if (member == null) {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.UNAUTHORIZED, "User not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HuertosUserRole role = HuertosUserRole.USER;
|
||||||
|
if (member.getRole() != null) {
|
||||||
|
role = member.getRole();
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.put("userId", userId);
|
||||||
|
ctx.put("role", role);
|
||||||
|
ctx.put("userEntity", member);
|
||||||
|
|
||||||
|
if (allowedRoles.length == 0 || isRoleAllowed(role, allowedRoles)) {
|
||||||
|
ctx.next();
|
||||||
|
} else {
|
||||||
|
JsonUtil.sendJson(ctx, ApiStatus.FORBIDDEN, "Forbidden");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public class MemberService {
|
|||||||
return Future.failedFuture(new ForbiddenException("User is not active"));
|
return Future.failedFuture(new ForbiddenException("User is not active"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return userMetadataDAO.getById(user.getUser_id()).compose(metadata -> {
|
return userMetadataDAO.getById(user.getUser_id()).compose(metadata -> {
|
||||||
if (metadata.getStatus() != HuertosUserStatus.ACTIVE) {
|
if (metadata.getStatus() != HuertosUserStatus.ACTIVE) {
|
||||||
return Future.failedFuture(new ForbiddenException("User is not active"));
|
return Future.failedFuture(new ForbiddenException("User is not active"));
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import io.vertx.core.json.JsonObject;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
import net.miarma.api.backlib.Constants.HuertosUserStatus;
|
import net.miarma.api.backlib.Constants.HuertosUserStatus;
|
||||||
import net.miarma.api.backlib.Constants.HuertosUserType;
|
import net.miarma.api.backlib.Constants.HuertosUserType;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.db.DatabaseProvider;
|
import net.miarma.api.backlib.db.DatabaseProvider;
|
||||||
import net.miarma.api.backlib.util.EventBusUtil;
|
import net.miarma.api.backlib.util.EventBusUtil;
|
||||||
import net.miarma.api.backlib.util.NameCensorer;
|
import net.miarma.api.backlib.util.NameCensorer;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import io.vertx.core.Promise;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.db.DatabaseProvider;
|
import net.miarma.api.backlib.db.DatabaseProvider;
|
||||||
import net.miarma.api.backlib.util.RouterUtil;
|
import net.miarma.api.backlib.util.RouterUtil;
|
||||||
import net.miarma.api.microservices.huertos.routing.HuertosLogicRouter;
|
import net.miarma.api.microservices.huertos.routing.HuertosLogicRouter;
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package net.miarma.api.microservices.huertos.verticles;
|
|||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
import io.vertx.core.AbstractVerticle;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
import net.miarma.api.backlib.LogAccumulator;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
import net.miarma.api.backlib.log.LogAccumulator;
|
||||||
import net.miarma.api.backlib.util.DeploymentUtil;
|
import net.miarma.api.backlib.util.DeploymentUtil;
|
||||||
|
|
||||||
public class HuertosMainVerticle extends AbstractVerticle {
|
public class HuertosMainVerticle extends AbstractVerticle {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>huertosdecine</artifactId>
|
<artifactId>huertosdecine</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>23</maven.compiler.source>
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
@@ -20,36 +20,8 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>backlib</artifactId>
|
<artifactId>backlib</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>ME-HuertosDeCine</finalName>
|
|
||||||
<plugins>
|
|
||||||
<!-- Maven Shade Plugin -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.5.3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<transformers>
|
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
|
||||||
<mainClass>net.miarma.api.microservices.huertosdecine.CineMainVerticle</mainClass>
|
|
||||||
</transformer>
|
|
||||||
</transformers>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.miarma.api.microservices.huertosdecine.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IUserRole;
|
||||||
|
|
||||||
|
public enum CineUserRole implements IUserRole {
|
||||||
|
USER(0),
|
||||||
|
ADMIN(1);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
CineUserRole(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CineUserRole fromInt(int i) {
|
||||||
|
for (CineUserRole role : values()) {
|
||||||
|
if (role.value == i) return role;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid CineUserRole value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,8 @@ package net.miarma.api.microservices.huertosdecine.handlers;
|
|||||||
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
import net.miarma.api.microservices.huertosdecine.entities.MovieEntity;
|
import net.miarma.api.microservices.huertosdecine.entities.MovieEntity;
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ public class CineAuthGuard extends AbstractAuthGuard<ViewerEntity, CineUserRole>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean hasPermission(ViewerEntity user, CineUserRole role) {
|
protected boolean hasPermission(ViewerEntity user, CineUserRole userRole) {
|
||||||
return user.getRole() == CineUserRole.ADMIN;
|
return user.getRole() == CineUserRole.ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import io.vertx.core.json.JsonObject;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.db.DatabaseProvider;
|
import net.miarma.api.backlib.db.DatabaseProvider;
|
||||||
import net.miarma.api.backlib.util.EventBusUtil;
|
import net.miarma.api.backlib.util.EventBusUtil;
|
||||||
import net.miarma.api.backlib.util.RouterUtil;
|
import net.miarma.api.backlib.util.RouterUtil;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import io.vertx.core.Promise;
|
|||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.handler.BodyHandler;
|
import io.vertx.ext.web.handler.BodyHandler;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.db.DatabaseProvider;
|
import net.miarma.api.backlib.db.DatabaseProvider;
|
||||||
import net.miarma.api.backlib.util.RouterUtil;
|
import net.miarma.api.backlib.util.RouterUtil;
|
||||||
import net.miarma.api.microservices.huertosdecine.routing.CineLogicRouter;
|
import net.miarma.api.microservices.huertosdecine.routing.CineLogicRouter;
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package net.miarma.api.microservices.huertosdecine.verticles;
|
|||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
import io.vertx.core.AbstractVerticle;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
import net.miarma.api.backlib.LogAccumulator;
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
|
import net.miarma.api.backlib.log.LogAccumulator;
|
||||||
import net.miarma.api.backlib.util.DeploymentUtil;
|
import net.miarma.api.backlib.util.DeploymentUtil;
|
||||||
|
|
||||||
public class CineMainVerticle extends AbstractVerticle {
|
public class CineMainVerticle extends AbstractVerticle {
|
||||||
|
|||||||
@@ -1,8 +1,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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>miarmacraft</artifactId>
|
<artifactId>minecraft</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>23</maven.compiler.source>
|
<maven.compiler.source>23</maven.compiler.source>
|
||||||
@@ -20,36 +20,8 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.miarma.api</groupId>
|
<groupId>net.miarma.api</groupId>
|
||||||
<artifactId>backlib</artifactId>
|
<artifactId>backlib</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>ME-MiarmaCraft</finalName>
|
|
||||||
<plugins>
|
|
||||||
<!-- Maven Shade Plugin -->
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.5.3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<transformers>
|
|
||||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
|
||||||
<mainClass>net.miarma.api.microservices.miarmacraft.MMCMainVerticle</mainClass>
|
|
||||||
</transformer>
|
|
||||||
</transformers>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.handlers;
|
|
||||||
|
|
||||||
public class ModLogicHandler {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.dao;
|
package net.miarma.api.microservices.minecraft.dao;
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
@@ -8,7 +8,7 @@ import net.miarma.api.backlib.db.DatabaseManager;
|
|||||||
import net.miarma.api.backlib.db.QueryBuilder;
|
import net.miarma.api.backlib.db.QueryBuilder;
|
||||||
import net.miarma.api.backlib.http.QueryFilters;
|
import net.miarma.api.backlib.http.QueryFilters;
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
import net.miarma.api.microservices.miarmacraft.entities.ModEntity;
|
import net.miarma.api.microservices.minecraft.entities.ModEntity;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.dao;
|
package net.miarma.api.microservices.minecraft.dao;
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
@@ -8,7 +8,7 @@ import net.miarma.api.backlib.db.DatabaseManager;
|
|||||||
import net.miarma.api.backlib.db.QueryBuilder;
|
import net.miarma.api.backlib.db.QueryBuilder;
|
||||||
import net.miarma.api.backlib.http.QueryFilters;
|
import net.miarma.api.backlib.http.QueryFilters;
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
import net.miarma.api.microservices.miarmacraft.entities.PlayerEntity;
|
import net.miarma.api.microservices.minecraft.entities.PlayerEntity;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.dao;
|
package net.miarma.api.microservices.minecraft.dao;
|
||||||
|
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
@@ -8,7 +8,7 @@ import net.miarma.api.backlib.db.DatabaseManager;
|
|||||||
import net.miarma.api.backlib.db.QueryBuilder;
|
import net.miarma.api.backlib.db.QueryBuilder;
|
||||||
import net.miarma.api.backlib.http.QueryFilters;
|
import net.miarma.api.backlib.http.QueryFilters;
|
||||||
import net.miarma.api.backlib.http.QueryParams;
|
import net.miarma.api.backlib.http.QueryParams;
|
||||||
import net.miarma.api.microservices.miarmacraft.entities.UserMetadataEntity;
|
import net.miarma.api.microservices.minecraft.entities.UserMetadataEntity;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.entities;
|
package net.miarma.api.microservices.minecraft.entities;
|
||||||
|
|
||||||
import io.vertx.sqlclient.Row;
|
import io.vertx.sqlclient.Row;
|
||||||
import net.miarma.api.backlib.Constants.MMCModStatus;
|
import net.miarma.api.backlib.Constants.MMCModStatus;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.entities;
|
package net.miarma.api.microservices.minecraft.entities;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.entities;
|
package net.miarma.api.microservices.minecraft.entities;
|
||||||
|
|
||||||
import io.vertx.sqlclient.Row;
|
import io.vertx.sqlclient.Row;
|
||||||
import net.miarma.api.backlib.Constants.MMCUserRole;
|
import net.miarma.api.backlib.Constants.MMCUserRole;
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package net.miarma.api.microservices.minecraft.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum MinecraftModStatus implements IValuableEnum {
|
||||||
|
ACTIVE(0),
|
||||||
|
INACTIVE(1);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
MinecraftModStatus(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinecraftModStatus fromInt(int i) {
|
||||||
|
for (MinecraftModStatus status : values()) {
|
||||||
|
if (status.value == i) return status;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid MinecraftModStatus value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.miarma.api.microservices.minecraft.enums;
|
||||||
|
|
||||||
|
import net.miarma.api.backlib.interfaces.IUserRole;
|
||||||
|
import net.miarma.api.backlib.interfaces.IValuableEnum;
|
||||||
|
|
||||||
|
public enum MinecraftUserRole implements IUserRole, IValuableEnum {
|
||||||
|
PLAYER(0),
|
||||||
|
ADMIN(1);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
MinecraftUserRole(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinecraftUserRole fromInt(int i) {
|
||||||
|
for (MinecraftUserRole role : values()) {
|
||||||
|
if (role.value == i) return role;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Invalid MinecraftUserRole value: " + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.handlers;
|
package net.miarma.api.microservices.minecraft.handlers;
|
||||||
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.ConfigManager;
|
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
|
import net.miarma.api.backlib.config.ConfigManager;
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
import net.miarma.api.microservices.miarmacraft.entities.ModEntity;
|
|
||||||
import net.miarma.api.microservices.miarmacraft.services.ModService;
|
|
||||||
import net.miarma.api.backlib.util.JsonUtil;
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
|
import net.miarma.api.microservices.minecraft.entities.ModEntity;
|
||||||
|
import net.miarma.api.microservices.minecraft.services.ModService;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package net.miarma.api.microservices.minecraft.handlers;
|
||||||
|
|
||||||
|
public class ModLogicHandler {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package net.miarma.api.microservices.miarmacraft.handlers;
|
package net.miarma.api.microservices.minecraft.handlers;
|
||||||
|
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.sqlclient.Pool;
|
import io.vertx.sqlclient.Pool;
|
||||||
import net.miarma.api.backlib.Constants;
|
import net.miarma.api.backlib.Constants;
|
||||||
import net.miarma.api.backlib.http.ApiStatus;
|
import net.miarma.api.backlib.http.ApiStatus;
|
||||||
import net.miarma.api.microservices.miarmacraft.entities.PlayerEntity;
|
|
||||||
import net.miarma.api.microservices.miarmacraft.services.PlayerService;
|
|
||||||
import net.miarma.api.backlib.util.JsonUtil;
|
import net.miarma.api.backlib.util.JsonUtil;
|
||||||
|
import net.miarma.api.microservices.minecraft.entities.PlayerEntity;
|
||||||
|
import net.miarma.api.microservices.minecraft.services.PlayerService;
|
||||||
|
|
||||||
public class PlayerDataHandler {
|
public class PlayerDataHandler {
|
||||||
private final PlayerService playerService;
|
private final PlayerService playerService;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user