Finished: Huertos de Cine

This commit is contained in:
Jose
2025-06-11 07:06:06 +02:00
parent 46c8da9275
commit c6be6c1693
8 changed files with 84 additions and 14 deletions

2
.gitignore vendored
View File

@@ -1,5 +1,5 @@
/src/main/resources/.env
/target/*
/target/
/bin/
/inserts.sql
/last_dump.sql

View File

@@ -59,6 +59,20 @@ public class UserMetadataDAO implements DataAccessObject<UserMetadataEntity> {
return promise.future();
}
public Future<UserMetadataEntity> upsert(UserMetadataEntity metadata) {
Promise<UserMetadataEntity> promise = Promise.promise();
String query = QueryBuilder
.upsert(metadata, "user_id")
.build();
db.executeOne(query, UserMetadataEntity.class,
_ -> promise.complete(metadata),
promise::fail
);
return promise.future();
}
@Override
public Future<UserMetadataEntity> update(UserMetadataEntity metadata) {
Promise<UserMetadataEntity> promise = Promise.promise();

View File

@@ -5,6 +5,7 @@ import io.vertx.sqlclient.Pool;
import net.miarma.api.common.Constants;
import net.miarma.api.common.http.ApiStatus;
import net.miarma.api.common.http.QueryParams;
import net.miarma.api.microservices.huertosdecine.entities.UserMetadataEntity;
import net.miarma.api.microservices.huertosdecine.entities.ViewerEntity;
import net.miarma.api.microservices.huertosdecine.services.ViewerService;
import net.miarma.api.util.JsonUtil;
@@ -40,6 +41,14 @@ public class ViewerDataHandler {
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void createMetadata(RoutingContext ctx) {
UserMetadataEntity userMetadata = Constants.GSON.fromJson(ctx.body().asString(), UserMetadataEntity.class);
viewerService.createMetadata(userMetadata)
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.CREATED, result))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
public void update(RoutingContext ctx) {
ViewerEntity viewer = Constants.GSON.fromJson(ctx.body().asString(), ViewerEntity.class);
@@ -55,4 +64,5 @@ public class ViewerDataHandler {
.onSuccess(result -> JsonUtil.sendJson(ctx, ApiStatus.NO_CONTENT, null))
.onFailure(err -> JsonUtil.sendJson(ctx, ApiStatus.fromException(err), null, err.getMessage()));
}
}

View File

@@ -45,5 +45,6 @@ public class CineDataRouter {
router.post(CineEndpoints.VIEWERS).handler(AuthGuard.cineAdmin(viewerService)).handler(hViewerData::create);
router.put(CineEndpoints.VIEWER).handler(AuthGuard.cineAdmin(viewerService)).handler(hViewerData::update);
router.delete(CineEndpoints.VIEWER).handler(AuthGuard.cineAdmin(viewerService)).handler(hViewerData::delete);
router.post(CineEndpoints.VIEWER_METADATA).handler(AuthGuard.cineAdmin(viewerService)).handler(hViewerData::createMetadata);
}
}

View File

@@ -10,6 +10,7 @@ public class CineEndpoints {
/* OK */ public static final String VIEWERS = Constants.CINE_PREFIX + "/viewers"; // GET, POST, PUT, DELETE
/* OK */ public static final String VIEWER = Constants.CINE_PREFIX + "/viewers/:viewer_id"; // GET, PUT, DELETE
public static final String VIEWER_METADATA = Constants.CINE_PREFIX + "/viewers/metadata"; // POST, (PUT)
// logic layer
/* OK */ public static final String MOVIE_VOTES = Constants.CINE_PREFIX + "/movies/:movie_id/votes"; // GET, POST, PUT, DELETE

View File

@@ -36,7 +36,7 @@ public class CineLogicRouter {
router.post(CineEndpoints.LOGIN).handler(hViewerLogic::login);
router.get(CineEndpoints.VIEWER_VOTES_BY_MOVIE).handler(AuthGuard.cineAdmin(viewerService)).handler(hViewerLogic::getVotesOnMovieByUserId);
router.get(CineEndpoints.MOVIE_VOTES).handler(AuthGuard.cineAdmin(viewerService)).handler(hVoteLogic::getVotes);
router.get(CineEndpoints.MOVIE_VOTES).handler(AuthGuard.check()).handler(hVoteLogic::getVotes);
router.post(CineEndpoints.MOVIE_VOTES).handler(AuthGuard.check()).handler(hVoteLogic::addVote);
router.delete(CineEndpoints.MOVIE_VOTES).handler(AuthGuard.check()).handler(hVoteLogic::deleteVote);
router.get(CineEndpoints.SELF_VOTES).handler(AuthGuard.check()).handler(hVoteLogic::getVoteSelf);

View File

@@ -17,9 +17,11 @@ import net.miarma.api.microservices.huertosdecine.dao.UserMetadataDAO;
import net.miarma.api.microservices.huertosdecine.dao.ViewerDAO;
import net.miarma.api.microservices.huertosdecine.entities.UserMetadataEntity;
import net.miarma.api.microservices.huertosdecine.entities.ViewerEntity;
import net.miarma.api.util.UserNameGenerator;
import org.mindrot.jbcrypt.BCrypt;
import javax.swing.text.View;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.List;
@@ -107,25 +109,35 @@ public class ViewerService {
public Future<ViewerEntity> create(ViewerEntity viewer) {
viewer.setPassword(PasswordHasher.hash(viewer.getPassword()));
if (viewer.getEmail().isBlank()) viewer.setEmail(null);
if (viewer.getEmail() == null || viewer.getEmail().isBlank()) viewer.setEmail(null);
String baseName = viewer.getDisplay_name().split(" ")[0].toLowerCase();
String userName;
try {
userName = UserNameGenerator.generateUserName(baseName, viewer.getDisplay_name(), 3);
viewer.setUser_name(userName);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
System.out.println(UserEntity.fromViewerEntity(viewer));
return userDAO.insert(UserEntity.fromViewerEntity(viewer)).compose(user -> {
UserMetadataEntity metadata = UserMetadataEntity.fromViewerEntity(viewer);
metadata.setUser_id(user.getUser_id());
return userMetadataDAO.insert(metadata).compose(meta -> {
String baseName = viewer.getDisplay_name().split(" ")[0].toLowerCase();
char[] hash = {};
PasswordHasher.hash(viewer.getDisplay_name()).getChars(0, 6, hash, 0);
String userName = baseName + "-" + Arrays.toString(hash);
user.setUser_name(userName);
return userDAO.update(user).map(updatedUser -> new ViewerEntity(updatedUser, meta));
});
return userMetadataDAO.upsert(metadata).compose(meta ->
userDAO.update(user).map(updatedUser -> new ViewerEntity(updatedUser, meta)));
});
}
public Future<UserMetadataEntity> createMetadata(UserMetadataEntity userMetadata) {
if (userMetadata.getUser_id() == null) {
return Future.failedFuture(new BadRequestException("User ID is required"));
}
return userMetadataDAO.upsert(userMetadata).compose(Future::succeededFuture);
}
public Future<ViewerEntity> update(ViewerEntity viewer) {
return getById(viewer.getUser_id()).compose(existing -> {
if (existing == null) {

View File

@@ -0,0 +1,32 @@
package net.miarma.api.util;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class UserNameGenerator {
public static String generateUserName(String baseName, String input, int hashBytesCount) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder hexHash = new StringBuilder();
for (int i = 0; i < hashBytesCount && i < hash.length; i++) {
hexHash.append(String.format("%02x", hash[i]));
}
return baseName + "-" + hexHash.toString();
}
public static void main(String[] args) {
String baseName = "antonio";
String input = "ANTONIO GARCÍA MORENO";
try {
String userName = generateUserName(baseName, input, 3); // 3 bytes = 6 hex chars
System.out.println(userName); // Ej: antonio-4f7a9b
} catch (NoSuchAlgorithmException e) {
System.err.println("SHA-256 no está disponible en este sistema");
}
}
}