Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIR-1363 Adapt deprecated access key api #1076

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package org.mycore.mir.authorization;

import java.util.Date;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.mycore.access.MCRAccessManager;
import org.mycore.access.strategies.MCRAccessCheckStrategy;
import org.mycore.datamodel.metadata.MCRObjectID;
import org.mycore.mcr.acl.accesskey.MCRAccessKeyConfig;
import org.mycore.mcr.acl.accesskey.MCRAccessKeyServiceFactory;
import org.mycore.mcr.acl.accesskey.dto.MCRAccessKeyDto;

/**
* Strategy class for checking access permissions on objects based on access keys.
* This class implements the {@link MCRAccessCheckStrategy} interface and provides methods
* to check permissions for both string-based object IDs and {@link MCRObjectID} instances.
*/
public class MIRAccessKeyObjectStrategy implements MCRAccessCheckStrategy {

private static final Logger LOGGER = LogManager.getLogger();

@Override
public boolean checkPermission(String id, String permission) {
if (!MCRObjectID.isValid(id)) {
return false;
}
return checkContextHasValidAccessKey(MCRObjectID.getInstance(id), permission);
}

/**
* Checks whether the specified permission is granted for the given {@link MCRObjectID}.
*
* @param objectId the {@link MCRObjectID} instance representing the object
* @param permission the requested permission (e.g., "read", "write")
* @return {@code true} if the permission is granted, {@code false} otherwise
*/
public boolean checkContextHasValidAccessKey(MCRObjectID objectId, String permission) {
if (!MCRAccessKeyConfig.getAllowedObjectTypes().contains(objectId.getTypeId())) {
return false;
}
final String sanitizedPermission = sanitizePermission(permission);
if (!(MCRAccessManager.PERMISSION_WRITE.equals(sanitizedPermission)
|| MCRAccessManager.PERMISSION_READ.equals(sanitizedPermission))) {
return false;
}
if (MCRAccessKeyConfig.getAllowedSessionPermissionTypes().contains(sanitizedPermission)) {
if (checkSessionHasValidObjectAccessKey(objectId, permission)) {
return true;
}
}
return checkUserHasValidObjectAccessKey(objectId, permission);
}

private static String sanitizePermission(String permission) {
if (MCRAccessManager.PERMISSION_VIEW.equals(permission)
|| MCRAccessManager.PERMISSION_PREVIEW.equals(permission)) {
LOGGER.debug("Mapped {} to read.", permission);
return MCRAccessManager.PERMISSION_READ;
}
return permission;
}

private boolean checkSessionHasValidObjectAccessKey(MCRObjectID objectId, String permission) {
final MCRAccessKeyDto accessKeyDto
= MCRAccessKeyServiceFactory.getAccessKeySessionService().findActiveAccessKey(objectId.toString());
if (accessKeyDto != null) {
LOGGER.debug("Found match in access key strategy for {} on {} in session.", permission,
objectId);
return checkObjectAccessKey(accessKeyDto, permission);
}
return false;
}

private boolean checkUserHasValidObjectAccessKey(MCRObjectID objectId, String permission) {
final MCRAccessKeyDto accessKeyDto
= MCRAccessKeyServiceFactory.getAccessKeyUserService().findActiveAccessKey(objectId.toString());
if (accessKeyDto != null) {
LOGGER.debug("Found match in access key strategy for {} on {} in session.", permission,
objectId);
return checkObjectAccessKey(accessKeyDto, permission);
}
return false;
}

private boolean checkObjectAccessKey(MCRAccessKeyDto accessKeyDto, String permission) {
if (MCRAccessManager.PERMISSION_READ.equals(permission)
|| MCRAccessManager.PERMISSION_WRITE.equals(permission)) {
if (Boolean.FALSE.equals(accessKeyDto.getActive())) {
return false;
}
final Date expiration = accessKeyDto.getExpiration();
if (expiration != null && new Date().after(expiration)) {
return false;
}
if ((permission.equals(MCRAccessManager.PERMISSION_READ)
&& accessKeyDto.getPermission().equals(MCRAccessManager.PERMISSION_READ))
|| accessKeyDto.getPermission().equals(MCRAccessManager.PERMISSION_WRITE)) {
LOGGER.debug("Access granted.");
return true;
}
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@
import org.mycore.datamodel.classifications2.MCRCategoryID;
import org.mycore.datamodel.metadata.MCRMetadataManager;
import org.mycore.datamodel.metadata.MCRObjectID;
import org.mycore.mcr.acl.accesskey.MCRAccessKeyManager;
import org.mycore.mcr.acl.accesskey.MCRAccessKeyUtils;
import org.mycore.mcr.acl.accesskey.model.MCRAccessKey;
import org.mycore.mcr.acl.accesskey.strategy.MCRAccessKeyStrategyHelper;
import org.mycore.mods.MCRMODSEmbargoUtils;
import org.mycore.pi.MCRPIManager;
import org.mycore.pi.MCRPIRegistrationInfo;
Expand Down Expand Up @@ -81,6 +77,8 @@ public class MIRStrategy implements MCRAccessCheckStrategy {

private static final MCRCreatorRuleStrategy CREATOR_STRATEGY = new MCRCreatorRuleStrategy();

private static final MIRAccessKeyObjectStrategy ACCESS_KEY_OBJECT_STRATEGY = new MIRAccessKeyObjectStrategy();

private static final long CACHE_TIME = 1000 * 60 * 60;

private final List<String> accessClasses;
Expand All @@ -98,43 +96,6 @@ public MIRStrategy() {
accessImpl = MCRAccessManager.getAccessImpl();
}

private boolean hasValidAccessKey(final MCRObjectID objectId, final String permission) {
boolean isWritePermission = MCRAccessManager.PERMISSION_WRITE.equals(permission);
boolean isReadPermission = MCRAccessManager.PERMISSION_READ.equals(permission);
if (isWritePermission || isReadPermission) {
if (MCRAccessKeyUtils.isAccessKeyForSessionAllowed(permission)) {
final String sessionSecret = MCRAccessKeyUtils.getAccessKeySecretFromCurrentSession(objectId);
if (sessionSecret != null) {
final MCRAccessKey accessKey = MCRAccessKeyManager.getAccessKeyWithSecret(objectId, sessionSecret);
if (accessKey != null) {
LOGGER.debug("Found match in access key strategy for {} on {} in session.", permission,
objectId);
if (MCRAccessKeyStrategyHelper.verifyAccessKey(permission, accessKey)) {
return true;
}
}
if (accessKey == null || permission.equals(MCRAccessManager.PERMISSION_READ)) {
MCRAccessKeyUtils.removeAccessKeySecretFromCurrentSession(objectId);
}
}
}
final String userSecret = MCRAccessKeyUtils.getAccessKeySecretFromCurrentUser(objectId);
if (userSecret != null) {
final MCRAccessKey accessKey = MCRAccessKeyManager.getAccessKeyWithSecret(objectId, userSecret);
if (accessKey != null) {
LOGGER.debug("Found match in access key strategy for {} on {} for user.", permission, objectId);
if (MCRAccessKeyStrategyHelper.verifyAccessKey(permission, accessKey)) {
return true;
}
}
if (accessKey == null || permission.equals(MCRAccessManager.PERMISSION_READ)) {
MCRAccessKeyUtils.removeAccessKeySecretFromCurrentUser(objectId);
}
}
}
return false;
}

private boolean checkObjectPermission(MCRObjectID objectId, String permission) {
LOGGER.debug("checkObjectPermission({}, {})", objectId, permission);

Expand All @@ -146,9 +107,8 @@ private boolean checkObjectPermission(MCRObjectID objectId, String permission) {

String permissionId = objectId.toString();

// 2. check read or write key of current user
if (MCRAccessKeyUtils.isAccessKeyForObjectTypeAllowed(objectId.getTypeId())
&& hasValidAccessKey(objectId, permission)) {
// 2. check read or write key
if (ACCESS_KEY_OBJECT_STRATEGY.checkContextHasValidAccessKey(objectId, permission)) {
return true;
}

Expand Down Expand Up @@ -212,11 +172,9 @@ private boolean checkDerivatePermission(MCRObjectID derivateId, String permissio
}
}

// 2. check read or write key of current user
if ((MCRAccessKeyUtils.isAccessKeyForObjectTypeAllowed(objectId.getTypeId())
&& hasValidAccessKey(objectId, permission))
|| (MCRAccessKeyUtils.isAccessKeyForObjectTypeAllowed(derivateId.getTypeId())
&& hasValidAccessKey(derivateId, permission))) {
// 2. check read or write key
if (ACCESS_KEY_OBJECT_STRATEGY.checkContextHasValidAccessKey(objectId, permission)
|| ACCESS_KEY_OBJECT_STRATEGY.checkContextHasValidAccessKey(derivateId, permission)) {
return true;
}

Expand Down Expand Up @@ -267,12 +225,12 @@ private boolean canEditPI() {

private Optional<MCRCategoryID> getAccessCategory(MCRObjectID objectId, MCRObjectID derivateId, String permission) {
String type = Stream.of(derivateId, objectId).filter(Objects::nonNull).map(MCRObjectID::getTypeId).findFirst()
.get();
.get();
List<MCRCategoryID> amc = getAccessMappedCategories(type, permission, accessClasses);
return Stream.of(derivateId, objectId)
.filter(Objects::nonNull)
.flatMap(id -> getAccessCategory(amc, id).stream())
.findFirst();
.filter(Objects::nonNull)
.flatMap(id -> getAccessCategory(amc, id).stream())
.findFirst();
}

private Optional<MCRCategoryID> getAccessCategory(List<MCRCategoryID> accessMappedCategories, MCRObjectID id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
/**
* This class contains EventHandler methods to manage access keys of
* MCRObjects and MCRDerivates.
*
*
* @author Ren\u00E9 Adler (eagle)
* @since 0.3
*/
@Deprecated
public class MIRAccessKeyEventHandler extends MCREventHandlerBase {

private static Logger LOGGER = LogManager.getLogger();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.mycore.mcr.acl.accesskey.model.MCRAccessKey;
import org.mycore.mir.authorization.accesskeys.backend.MIRAccessKeyPair;

@Deprecated
public final class MIRAccessKeyManager {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
* @author Ren\u00E9 Adler (eagle)
* @since 0.3
*/
@Deprecated
public abstract class MIRAccessKeyPairTransformer {

public static final JAXBContext JAXB_CONTEXT = initContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* @author Ren\u00E9 Adler (eagle)
*
*/
@Deprecated
public class MIRAccessKeyResolver implements URIResolver {

/* (non-Javadoc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
import org.jdom2.Element;
import org.mycore.common.MCRSessionMgr;
import org.mycore.common.MCRSystemUserInformation;
import org.mycore.common.MCRUserInformation;
import org.mycore.datamodel.metadata.MCRObjectID;
import org.mycore.frontend.servlets.MCRServlet;
import org.mycore.frontend.servlets.MCRServletJob;
import org.mycore.mcr.acl.accesskey.MCRAccessKeyUtils;
import org.mycore.mcr.acl.accesskey.MCRAccessKeyConfig;
import org.mycore.mcr.acl.accesskey.MCRAccessKeyServiceFactory;
import org.mycore.mcr.acl.accesskey.exception.MCRAccessKeyException;

import jakarta.servlet.http.HttpServletRequest;
Expand All @@ -38,59 +38,64 @@ public class MIRAccessKeyServlet extends MCRServlet {

private static final long serialVersionUID = 1L;

private static final String REDIRECT_URL_PARAMETER = "url";
private static final String QUERY_PARAM_ACTION = "action";

private static String getReturnURL(HttpServletRequest req) {
String returnURL = req.getParameter(REDIRECT_URL_PARAMETER);
if (returnURL == null) {
String referer = req.getHeader("Referer");
returnURL = (referer != null) ? referer : req.getContextPath() + "/";
}
return returnURL;
}
private static final String QUERY_PARAM_OBJ_ID = "objId";

private static final String QUERY_PARAM_REDIRECT_URL = "url";

/* (non-Javadoc)
* @see org.mycore.frontend.servlets.MCRServlet#doGetPost(org.mycore.frontend.servlets.MCRServletJob)
*/
@Override
protected void doGetPost(MCRServletJob job) throws Exception {
HttpServletRequest req = job.getRequest();
HttpServletResponse res = job.getResponse();
final MCRUserInformation userInfo = MCRSessionMgr.getCurrentSession().getUserInformation();
final boolean isGuest = userInfo.getUserID().equals(MCRSystemUserInformation.getGuestInstance().getUserID());
if (isGuest && !MCRAccessKeyUtils.isAccessKeyForSessionAllowed()) {
final HttpServletRequest req = job.getRequest();
final HttpServletResponse res = job.getResponse();
final boolean isGuest = checkCurrentUserIsGuest();
if (isGuest && MCRAccessKeyConfig.getAllowedSessionPermissionTypes().isEmpty()) {
res.sendError(HttpServletResponse.SC_FORBIDDEN, "Access can only be granted to personalized users");
return;
}
final Document doc = (Document) (job.getRequest().getAttribute("MCRXEditorSubmission"));
if (doc == null) {
if (doc == null || req.getParameter(QUERY_PARAM_ACTION) != null) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
final String action = req.getParameter("action");
final Element xml = doc.getRootElement();
final String objId = xml.getAttributeValue("objId");
final MCRObjectID mcrObjId = MCRObjectID.getInstance(objId);
if (action == null) {
final String value = xml.getTextTrim();
if (value == null || value.length() == 0) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing documentID or accessKey parameter");
return;
}
try {
if (isGuest) {
MCRAccessKeyUtils.addAccessKeySecretToCurrentSession(mcrObjId, value);
} else {
MCRAccessKeyUtils.addAccessKeySecretToCurrentUser(mcrObjId, value);
}
} catch(MCRAccessKeyException e) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Access key is unknown or not allowed.");
return;
}
} else {
final String objId = xml.getAttributeValue(QUERY_PARAM_OBJ_ID);
if (objId == null || !MCRObjectID.isValid(objId)) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
final String value = xml.getTextTrim();
if (value.isEmpty()) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing documentID or accessKey parameter");
return;
}
try {
if (isGuest) {
MCRAccessKeyServiceFactory.getAccessKeySessionService().activateAccessKey(objId, value);
} else {
MCRAccessKeyServiceFactory.getAccessKeyUserService().activateAccessKey(objId, value);
}
} catch (MCRAccessKeyException e) {
res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Access key is unknown or not allowed.");
return;
}
res.sendRedirect(getReturnURL(req));
}

private static boolean checkCurrentUserIsGuest() {
return MCRSessionMgr.getCurrentSession().getUserInformation().getUserID()
.equals(MCRSystemUserInformation.getGuestInstance().getUserID());
}

private static String getReturnURL(HttpServletRequest req) {
String returnURL = req.getParameter(QUERY_PARAM_REDIRECT_URL);
if (returnURL == null) {
String referer = req.getHeader("Referer");
returnURL = (referer != null) ? referer : req.getContextPath() + "/";
}
return returnURL;
}
}
Loading
Loading