Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see .
*/
package org.mycore.access;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jdom2.Element;
import org.mycore.access.strategies.MCRAccessCheckStrategy;
import org.mycore.access.strategies.MCRDerivateIDStrategy;
import org.mycore.backend.jpa.MCREntityManagerProvider;
import org.mycore.common.MCRException;
import org.mycore.common.MCRUserInformation;
import org.mycore.common.config.MCRConfiguration2;
import org.mycore.common.events.MCRShutdownHandler;
import org.mycore.datamodel.metadata.MCRMetadataManager;
import org.mycore.datamodel.metadata.MCRObjectID;
import org.mycore.util.concurrent.MCRFixedUserCallable;
/**
* @author Thomas Scheffler
* @version $Revision$ $Date$
*/
public class MCRAccessManager {
private static final MCRAccessCacheManager ACCESS_CACHE = new MCRAccessCacheManager();
public static final Logger LOGGER = LogManager.getLogger(MCRAccessManager.class);
public static final String PERMISSION_READ = "read";
public static final String PERMISSION_WRITE = "writedb";
public static final String PERMISSION_DELETE = "deletedb";
public static final String PERMISSION_PREVIEW = "preview";
public static final String PERMISSION_VIEW = "view";
private static final ExecutorService EXECUTOR_SERVICE;
static {
EXECUTOR_SERVICE = Executors.newWorkStealingPool();
MCRShutdownHandler.getInstance().addCloseable(EXECUTOR_SERVICE::shutdownNow);
}
public static MCRAccessInterface getAccessImpl() {
return MCRConfiguration2.getSingleInstanceOf("MCR.Access.Class", MCRAccessBaseImpl.class).get();
}
private static MCRAccessCheckStrategy getAccessStrategy() {
return MCRConfiguration2.getInstanceOf("MCR.Access.Strategy.Class")
.orElseGet(MCRDerivateIDStrategy::new);
}
/**
* adds an access rule for an MCRObjectID to an access system.
*
* @param id
* the MCRObjectID of the object
* @param permission
* the access permission for the rule
* @param rule
* the access rule
* @param description
* description for the given access rule, e.g. "allows public access"
* @throws MCRException
* if an error was occurred
* @see MCRAccessInterface#addRule(String, String, Element, String)
*/
public static void addRule(MCRObjectID id, String permission, Element rule, String description)
throws MCRException {
getAccessImpl().addRule(id.toString(), permission, rule, description);
}
/**
* adds an access rule for an ID to an access system.
*
* @param id
* the ID of the object as String
* @param permission
* the access permission for the rule
* @param rule
* the access rule
* @param description
* description for the given access rule, e.g. "allows public access"
* @throws MCRException
* if an error was occurred
* @see MCRAccessInterface#addRule(String, String, Element, String)
*/
public static void addRule(String id, String permission, Element rule, String description)
throws MCRException {
getAccessImpl().addRule(id, permission, rule, description);
}
/**
* removes the permission rule for the MCRObjectID.
*
* @param id
* the MCRObjectID of an object
* @param permission
* the access permission for the rule
* @throws MCRException
* if an error was occurred
* @see MCRAccessInterface#removeRule(String, String)
*/
public static void removeRule(MCRObjectID id, String permission) throws MCRException {
getAccessImpl().removeRule(id.toString(), permission);
}
/**
* removes the permission rule for the ID.
*
* @param id
* the ID of an object as String
* @param permission
* the access permission for the rule
* @throws MCRException
* if an error was occurred
* @see MCRAccessInterface#removeRule(String, String)
*/
public static void removeRule(String id, String permission) throws MCRException {
getAccessImpl().removeRule(id, permission);
}
/**
* removes all rules for the MCRObjectID.
*
* @param id
* the MCRObjectID of an object
* @throws MCRException
* if an error was occurred
* @see MCRAccessInterface#removeRule(String)
*/
public static void removeAllRules(MCRObjectID id) throws MCRException {
getAccessImpl().removeAllRules(id.toString());
}
/**
* updates an access rule for an MCRObjectID.
*
* @param id
* the MCRObjectID of the object
* @param permission
* the access permission for the rule
* @param rule
* the access rule
* @param description
* description for the given access rule, e.g. "allows public access"
* @throws MCRException
* if an error was occurred
* @see MCRAccessInterface#updateRule(String, String, Element, String)
*/
public static void updateRule(MCRObjectID id, String permission, Element rule, String description)
throws MCRException {
getAccessImpl().updateRule(id.toString(), permission, rule, description);
}
/**
* updates an access rule for an ID.
*
* @param id
* the ID of the object
* @param permission
* the access permission for the rule
* @param rule
* the access rule
* @param description
* description for the given access rule, e.g. "allows public access"
* @throws MCRException
* if an error was occurred
* @see MCRAccessInterface#updateRule(String, String, Element, String)
*/
public static void updateRule(String id, String permission, Element rule, String description)
throws MCRException {
getAccessImpl().updateRule(id, permission, rule, description);
}
/**
* determines whether the current user has the permission to perform a certain action.
*
* @param id
* the MCRObjectID of the object
* @param permission
* the access permission for the rule
* @return true if the access is allowed otherwise it return
* @see MCRAccessInterface#checkPermission(String, String)
*/
public static boolean checkPermission(MCRObjectID id, String permission) {
return checkPermission(id.toString(), permission);
}
/**
* checks if the current user has the permission to perform an action on the derivate metadata.
* @param derId the MCRObjectID of the derivate
* @param permission the access permission for the rule
* @return true, if the access is allowed
*/
public static boolean checkDerivateMetadataPermission(MCRObjectID derId, String permission) {
MCRObjectID objectId = MCRMetadataManager.getObjectId(derId, 10, TimeUnit.MINUTES);
if (objectId != null) {
return checkPermission(objectId, permission);
}
return checkPermission(derId.toString(), permission);
}
/**
* checks if the current user has the permission to perform an action on the derivate content.
* @param derId the MCRObjectID of the derivate
* @param permission the access permission for the rule
* @return true, if the access is allowed
*/
public static boolean checkDerivateContentPermission(MCRObjectID derId, String permission) {
return checkPermission(derId.toString(), permission);
}
/**
* determines whether the current user has the permission to perform a certain action.
*
* @param id
* the MCRObjectID of the object
* @param permission
* the access permission for the rule
* @return true if the permission for the id is given
*/
public static boolean checkPermission(String id, String permission) {
Boolean value = ACCESS_CACHE.isPermitted(id, permission);
if (value == null) {
value = getAccessStrategy().checkPermission(id, permission);
ACCESS_CACHE.cachePermission(id, permission, value);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("checkPermission id:{} permission:{} --> {}", id, permission, value);
}
return value;
}
/**
* determines whether the current user has the permission to perform a certain action.
*
* @param permission
* the access permission for the rule
* @return true if the permission exist
*/
public static boolean checkPermission(String permission) {
Boolean value = ACCESS_CACHE.isPermitted(null, permission);
if (value == null) {
value = getAccessImpl().checkPermission(permission);
ACCESS_CACHE.cachePermission(null, permission, value);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("checkPermission permission:{} --> {}", permission, value);
}
return value;
}
/**
* Invalidates the permission for current user on cache.
*
* @param id the {@link MCRObjectID}
* @param permission the access permission
*/
public static void invalidPermissionCache(String id, String permission) {
ACCESS_CACHE.removePermission(id, permission);
}
/**
* Invalidates the permission for current user on cache.
*
* @param permission the access permission
*/
public static void invalidPermissionCache(String permission) {
invalidPermissionCache(null, permission);
}
/**
* checks whether the current user has the permission to read/see a derivate check is also against the mcrobject,
* the derivate belongs to both checks must return true
* it is needed in MCRFileNodeServlet and MCRZipServlet
*
* @param derID
* String ID of a MyCoRe-Derivate
* @return true if the access is allowed otherwise it return false
* @deprecated use {@link #checkDerivateContentPermission(MCRObjectID, String)} or
* {@link #checkDerivateMetadataPermission(MCRObjectID, String)} instead with Strategy
* that also checks for the object.
*/
@Deprecated
public static boolean checkPermissionForReadingDerivate(String derID) {
// derID must be a derivate ID
boolean accessAllowed = false;
MCRObjectID objectId = MCRMetadataManager.getObjectId(MCRObjectID.getInstance(derID), 10, TimeUnit.MINUTES);
if (objectId != null) {
accessAllowed = checkPermission(objectId, PERMISSION_READ) && checkPermission(derID, PERMISSION_READ);
} else {
accessAllowed = checkPermission(derID, PERMISSION_READ);
LogManager.getLogger("MCRAccessManager.class").warn("no mcrobject could be found for derivate: {}", derID);
}
return accessAllowed;
}
/**
* lists all permissions defined for the id.
*
* @param id
* the ID of the object as String
* @return a List of all for id defined permissions
*/
public static Collection getPermissionsForID(String id) {
return getAccessImpl().getPermissionsForID(id);
}
/**
* lists all permissions defined for the id.
*
* @param id
* the MCRObjectID of the object
* @return a List of all for id defined permissions
*/
public static Collection getPermissionsForID(MCRObjectID id) {
return getAccessImpl().getPermissionsForID(id.toString());
}
/**
* return a rule, that allows something for everybody
*
* @return a rule, that allows something for everybody
*/
public static Element getTrueRule() {
Element condition = new Element("condition");
condition.setAttribute("format", "xml");
Element booleanOp = new Element("boolean");
booleanOp.setAttribute("operator", "true");
condition.addContent(booleanOp);
return condition;
}
/**
* return a rule, that forbids something for all, but superuser
*
* @return a rule, that forbids something for all, but superuser
*/
public static Element getFalseRule() {
Element condition = new Element("condition");
condition.setAttribute("format", "xml");
Element booleanOp = new Element("boolean");
booleanOp.setAttribute("operator", "false");
condition.addContent(booleanOp);
return condition;
}
/**
* return true if a rule for the id exist
*
* @param id
* the MCRObjectID of the object
* @param permission
* the access permission for the rule
*/
public static boolean hasRule(String id, String permission) {
return getAccessImpl().hasRule(id, permission);
}
public static CompletableFuture checkPermission(MCRUserInformation user, Supplier checkSuplier) {
return checkPermission(user, checkSuplier, EXECUTOR_SERVICE);
}
public static CompletableFuture checkPermission(MCRUserInformation user, Supplier checkSuplier,
ExecutorService es) {
return CompletableFuture.supplyAsync(getWrappedFixedUserCallable(user, checkSuplier), es);
}
private static Supplier getWrappedFixedUserCallable(MCRUserInformation user,
Supplier checkSuplier) {
Supplier check = () -> {
try {
return checkSuplier.get();
} finally {
MCREntityManagerProvider.getCurrentEntityManager().clear();
}
};
MCRFixedUserCallable mcrFixedUserCallable = new MCRFixedUserCallable<>(check::get, user);
return () -> {
try {
return mcrFixedUserCallable.call();
} catch (Exception e) {
LOGGER.error("Exception while running ACL check for user: {}", user.getUserID(), e);
return false;
}
};
}
}