/* * Copyright @ 2013 CurisTEC, S.A.S. All Rights Reserved. */ package net.curisit.securis.db; import java.io.Serializable; import java.util.Date; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EntityManager; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; import net.curisit.integrity.commons.Utils; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; /** * BlockedRequest *

* Persistent record marking a request (by hash) as blocked. * Primary key is the SHA-256 of the original request_data. * Useful to avoid replay/duplicate processing. * * Mapping details: * - Table: blocked_request * - PK: hash (SHA-256(request_data)) * - Optional relation 'blockedBy' for auditing. * * @author JRA * Last reviewed by JRA on Oct 7, 2025. */ @JsonAutoDetect @JsonInclude(Include.NON_NULL) @Entity @Table(name = "blocked_request") @JsonIgnoreProperties(ignoreUnknown = true) public class BlockedRequest implements Serializable { private static final long serialVersionUID = 1L; /** Unique SHA-256 hash of {@link #requestData}. */ @Id private String hash; /** Original request payload. */ @Column(name = "request_data") @JsonProperty("request_data") private String requestData; /** Server-side creation timestamp. */ @Column(name = "creation_timestamp") @JsonProperty("creation_timestamp") private Date creationTimestamp; /** User who blocked this request (optional, auditing). */ @JsonIgnore @ManyToOne @JoinColumn(name = "blocked_by") private User blockedBy; // --------------------------------------------------------------------- // Getters & setters // --------------------------------------------------------------------- /** * getCreationTimestamp

* Get the creation timestamp. * * @return creationTimestamp */ public Date getCreationTimestamp() { return creationTimestamp; } /** * setCreationTimestamp

* Set the creation timestamp. * * @param creationTimestamp */ public void setCreationTimestamp(Date creationTimestamp) { this.creationTimestamp = creationTimestamp; } /** * equals

* Identity based on primary key (hash). */ @Override public boolean equals(Object obj) { if (!(obj instanceof BlockedRequest)) return false; BlockedRequest other = (BlockedRequest) obj; return (hash == null && other.hash == null) || (hash != null && hash.equals(other.hash)); } /** * hashCode

* Hash based on primary key (hash). */ @Override public int hashCode() { return (hash == null ? 0 : hash.hashCode()); } /** * getRequestData

* Get the original serialized request data. * * @return requestData */ public String getRequestData() { return requestData; } /** * setRequestData

* Set the original request data and recompute the PK hash immediately. * Hash is computed as SHA-256 over the request string. * * @param requestData */ public void setRequestData(String requestData) { this.requestData = requestData; this.hash = generateHash(this.requestData); } /** * getBlockedBy

* Return the user who blocked this request (if any). * * @return blockedBy */ public User getBlockedBy() { return blockedBy; } /** * setBlockedBy

* Set the user who blocked this request. * * @param blockedBy */ public void setBlockedBy(User blockedBy) { this.blockedBy = blockedBy; } // --------------------------------------------------------------------- // Static helpers // --------------------------------------------------------------------- /** * generateHash

* Compute the SHA-256 hex string for the given request data. * * @param reqData * @return sha256(reqData) or null if reqData is null */ public static String generateHash(String reqData) { return (reqData != null ? Utils.sha256(reqData) : null); } /** * isRequestBlocked

* Check if a request payload is blocked by looking up its hash as the PK. * * @param requestData original payload * @param em JPA entity manager * @return true if an entry exists with the same hash */ public static boolean isRequestBlocked(String requestData, EntityManager em) { String hash = generateHash(requestData); BlockedRequest br = em.find(BlockedRequest.class, hash); return br != null; } }