EntityListener.java
/*
* The coLAB project
* Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.model.tools;
import ch.colabproject.colab.api.controller.EntityGatheringBagForPropagation;
import ch.colabproject.colab.api.controller.RequestManager;
import ch.colabproject.colab.api.controller.security.SecurityManager;
import ch.colabproject.colab.api.model.WithPermission;
import ch.colabproject.colab.api.model.WithTrackingData;
import ch.colabproject.colab.api.model.WithWebsocketChannels;
import javax.inject.Inject;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JPA Entity listener defined in orm.xml
* <p>
* The purposes are to
* <ul>
* <li>check permissions</li>
* <li>register modifications</li>
* <li>set tracking data</li>
* </ul>
*
* @author maxence
*/
public class EntityListener {
/** logger */
private static final Logger logger = LoggerFactory.getLogger(EntityListener.class);
/** To collect entities for later propagation */
@Inject
private EntityGatheringBagForPropagation wsEntityBag;
/** Security check */
@Inject
private SecurityManager securityManager;
/** request manager */
@Inject
private RequestManager requestManager;
/**
* Track all reads from database
*
* @param o just loaded object
*/
@PostLoad
public void onLoad(Object o) {
logger.trace("Load {}", o);
// Skip permission check if a condition assertion is already in progress
if (o instanceof WithPermission && !requestManager.isInSecurityTx()) {
securityManager.assertReadPermissionTx((WithPermission) o);
}
}
/**
* Track all insertions
*
* @param o just persisted object
*/
@PostPersist
public void onPersist(Object o) {
logger.trace("Persist {}", o);
// Skip permission check if a condition assertion is already in progress
if (o instanceof WithPermission && !requestManager.isInSecurityTx()) {
securityManager.assertCreatePermissionTx((WithPermission) o);
}
if (o instanceof WithWebsocketChannels) {
wsEntityBag.registerUpdate((WithWebsocketChannels) o);
}
}
/**
* Track all updates
*
* @param o just updated object
*/
@PostUpdate
public void onUpdate(Object o) {
logger.trace("Update {}", o);
// Skip permission check if a condition assertion is already in progress
if (o instanceof WithPermission && !requestManager.isInSecurityTx()) {
securityManager.assertUpdatePermissionTx((WithPermission) o);
}
if (o instanceof WithWebsocketChannels) {
wsEntityBag.registerUpdate((WithWebsocketChannels) o);
}
}
/**
* Before persist and before update, update tracking data
*
* @param o object to track
*/
@PrePersist
@PreUpdate
public void touch(Object o) {
if (!requestManager.isDoNotTrackChange() && o instanceof WithTrackingData) {
((WithTrackingData) o).touch(requestManager.getCurrentUser());
}
}
/**
* Intercept object just before their deletion
*
* @param o just deleted object
*/
@PreRemove
public void onDestroy(Object o) {
logger.trace("Destroy {}", o);
// Skip permission check if a condition assertion is already in progress
if (o instanceof WithPermission && !requestManager.isInSecurityTx()) {
securityManager.assertDeletePermissionTx((WithPermission) o);
}
if (o instanceof WithWebsocketChannels) {
wsEntityBag.registerDeletion((WithWebsocketChannels) o);
}
}
}