mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-1340: Couldn't cutoff closed folder
* includes a couple of fixes from the demo prep * override of MethodSecurityInterceptor to allow us to report detailed information when an AccessDenied exception is reported as the result of a capability evaluation failure. * integration tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/HEAD@69801 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -337,27 +337,32 @@ public abstract class CopyMoveLinkFileToBaseAction extends RMActionExecuterAbstr
|
||||
* @param lastAsFolder true if this is the last element of the pathe being created and it should be created as a folder. ignored if targetIsUnfiledRecords is true
|
||||
* @return
|
||||
*/
|
||||
private NodeRef createChild(Action action, NodeRef parent, String childName, boolean targetisUnfiledRecords, boolean lastAsFolder)
|
||||
private NodeRef createChild(final Action action, final NodeRef parent, final String childName, final boolean targetisUnfiledRecords, final boolean lastAsFolder)
|
||||
{
|
||||
NodeRef child = null;
|
||||
if(targetisUnfiledRecords)
|
||||
return AuthenticationUtil.runAsSystem(new RunAsWork<NodeRef>()
|
||||
{
|
||||
child = this.fileFolderService.create(parent, childName, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
|
||||
}
|
||||
else if(lastAsFolder)
|
||||
{
|
||||
child = recordFolderService.createRecordFolder(parent, childName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(nodeService.getType(parent)))
|
||||
public NodeRef doWork() throws Exception
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to execute " + action.getActionDefinitionName() + " action, because the destination path could not be created.");
|
||||
NodeRef child = null;
|
||||
if(targetisUnfiledRecords)
|
||||
{
|
||||
child = fileFolderService.create(parent, childName, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef();
|
||||
}
|
||||
else if(lastAsFolder)
|
||||
{
|
||||
child = recordFolderService.createRecordFolder(parent, childName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RecordsManagementModel.TYPE_RECORD_FOLDER.equals(nodeService.getType(parent)))
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to execute " + action.getActionDefinitionName() + " action, because the destination path could not be created.");
|
||||
}
|
||||
child = filePlanService.createRecordCategory(parent, childName);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
child = this.filePlanService.createRecordCategory(parent, childName);
|
||||
}
|
||||
return child;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -21,6 +21,7 @@ package org.alfresco.module.org_alfresco_module_rm.capability;
|
||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
@@ -196,21 +197,24 @@ public abstract class AbstractCapability extends RMSecurityCommon
|
||||
{
|
||||
String prefix = "hasPermissionRaw" + getName();
|
||||
int result = getTransactionCache(prefix, nodeRef);
|
||||
if (result != NOSET_VALUE)
|
||||
if (result == NOSET_VALUE)
|
||||
{
|
||||
return result;
|
||||
if (checkRmRead(nodeRef) == AccessDecisionVoter.ACCESS_DENIED)
|
||||
{
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = hasPermissionImpl(nodeRef);
|
||||
}
|
||||
|
||||
result = setTransactionCache(prefix, nodeRef, result);
|
||||
}
|
||||
|
||||
if (checkRmRead(nodeRef) == AccessDecisionVoter.ACCESS_DENIED)
|
||||
{
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = hasPermissionImpl(nodeRef);
|
||||
}
|
||||
|
||||
return setTransactionCache(prefix, nodeRef, result);
|
||||
|
||||
// Log information about evaluated capability
|
||||
RMMethodSecurityInterceptor.reportCapabilityStatus(getName(), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -29,6 +29,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.AbstractCapability;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.Capability;
|
||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind;
|
||||
import org.alfresco.module.org_alfresco_module_rm.security.RMMethodSecurityInterceptor;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -209,7 +210,12 @@ public class DeclarativeCapability extends AbstractCapability
|
||||
throw new AlfrescoRuntimeException("Capability condition " + conditionName + " does not exist. Check the configuration of the capability " + name + ".");
|
||||
}
|
||||
|
||||
// determine the actual value
|
||||
boolean actual = condition.evaluate(nodeRef);
|
||||
|
||||
// report information about condition (for exception reporting)
|
||||
RMMethodSecurityInterceptor.reportCapabilityCondition(getName(), condition.getName(), expected, actual);
|
||||
|
||||
if (expected != actual)
|
||||
{
|
||||
result = false;
|
||||
@@ -218,11 +224,10 @@ public class DeclarativeCapability extends AbstractCapability
|
||||
{
|
||||
logger.debug("FAIL: Condition " + condition.getName() + " failed for capability " + getName() + " on nodeRef " + nodeRef.toString());
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -277,7 +282,7 @@ public class DeclarativeCapability extends AbstractCapability
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.capability.AbstractCapability#hasPermissionImpl(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.capability.Capability#evaluate(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
@Override
|
||||
public int evaluate(NodeRef nodeRef)
|
||||
|
@@ -971,10 +971,11 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
||||
// apply cut off
|
||||
applyCutoff(nodeRef);
|
||||
|
||||
if (recordFolderService.isRecordFolder(nodeRef))
|
||||
// close the record folder if it isn't already closed!
|
||||
if (recordFolderService.isRecordFolder(nodeRef) &&
|
||||
!recordFolderService.isRecordFolderClosed(nodeRef))
|
||||
{
|
||||
// close folder (manually since we can't normall close a folder that is cut off!!
|
||||
nodeService.setProperty(nodeRef, PROP_IS_CLOSED, true);
|
||||
recordFolderService.closeRecordFolder(nodeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -984,11 +985,24 @@ public class DispositionServiceImpl extends ServiceBaseImpl
|
||||
}
|
||||
}
|
||||
|
||||
private void applyCutoff(NodeRef nodeRef)
|
||||
/**
|
||||
* Helper method to apply the cut off
|
||||
*
|
||||
* @param nodeRef node to cut off
|
||||
*/
|
||||
private void applyCutoff(final NodeRef nodeRef)
|
||||
{
|
||||
// Apply the cut off aspect and set cut off date
|
||||
Map<QName, Serializable> cutOffProps = new HashMap<QName, Serializable>(1);
|
||||
cutOffProps.put(PROP_CUT_OFF_DATE, new Date());
|
||||
nodeService.addAspect(nodeRef, ASPECT_CUT_OFF, cutOffProps);
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
// Apply the cut off aspect and set cut off date
|
||||
Map<QName, Serializable> cutOffProps = new HashMap<QName, Serializable>(1);
|
||||
cutOffProps.put(PROP_CUT_OFF_DATE, new Date());
|
||||
nodeService.addAspect(nodeRef, ASPECT_CUT_OFF, cutOffProps);
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,8 @@ import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanComponentKind
|
||||
import org.alfresco.module.org_alfresco_module_rm.fileplan.FilePlanService;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.record.RecordService;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
@@ -153,47 +155,57 @@ public class JSONConversionComponent extends org.alfresco.repo.jscript.app.JSONC
|
||||
* @param rootJSONObject root JSON object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addInfo(FileInfo nodeInfo, JSONObject rootJSONObject)
|
||||
private void addInfo(final FileInfo nodeInfo, JSONObject rootJSONObject)
|
||||
{
|
||||
String itemType = (String) rootJSONObject.get("type");
|
||||
QName itemTypeQName = QName.createQName(itemType, namespaceService);
|
||||
if (dictionaryService.isSubClass(itemTypeQName, ContentModel.TYPE_CONTENT))
|
||||
final QName itemTypeQName = QName.createQName(itemType, namespaceService);
|
||||
|
||||
NodeRef originatingLocation = AuthenticationUtil.runAsSystem(new RunAsWork<NodeRef>()
|
||||
{
|
||||
NodeRef nodeRef = nodeInfo.getNodeRef();
|
||||
List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
||||
|
||||
NodeRef originatingLocation = null;
|
||||
for (ChildAssociationRef parent : parentAssocs)
|
||||
{
|
||||
// FIXME: What if there is more than a secondary parent?
|
||||
if (!parent.isPrimary())
|
||||
public NodeRef doWork() throws Exception
|
||||
{
|
||||
NodeRef originatingLocation = null;
|
||||
|
||||
if (dictionaryService.isSubClass(itemTypeQName, ContentModel.TYPE_CONTENT))
|
||||
{
|
||||
originatingLocation = parent.getParentRef();
|
||||
|
||||
// only consider the non-RM parent otherwise we can
|
||||
// run into issues with frozen or transferring records
|
||||
if (!nodeService.hasAspect(originatingLocation, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT))
|
||||
NodeRef nodeRef = nodeInfo.getNodeRef();
|
||||
List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
|
||||
|
||||
for (ChildAssociationRef parent : parentAssocs)
|
||||
{
|
||||
// assume we have found the correct in-place location
|
||||
// FIXME when we support multiple in-place locations
|
||||
break;
|
||||
// FIXME: What if there is more than a secondary parent?
|
||||
if (!parent.isPrimary())
|
||||
{
|
||||
originatingLocation = parent.getParentRef();
|
||||
|
||||
// only consider the non-RM parent otherwise we can
|
||||
// run into issues with frozen or transferring records
|
||||
if (!nodeService.hasAspect(originatingLocation, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT))
|
||||
{
|
||||
// assume we have found the correct in-place location
|
||||
// FIXME when we support multiple in-place locations
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return originatingLocation;
|
||||
}
|
||||
|
||||
if (originatingLocation != null)
|
||||
});
|
||||
|
||||
if (originatingLocation != null)
|
||||
{
|
||||
String pathSeparator = "/";
|
||||
String displayPath = PathUtil.getDisplayPath(nodeService.getPath(originatingLocation), true);
|
||||
String[] displayPathElements = displayPath.split(pathSeparator);
|
||||
Object[] subPath = ArrayUtils.subarray(displayPathElements, 5, displayPathElements.length);
|
||||
StringBuffer originatingLocationPath = new StringBuffer();
|
||||
for (int i = 0; i < subPath.length; i++)
|
||||
{
|
||||
String pathSeparator = "/";
|
||||
String displayPath = PathUtil.getDisplayPath(nodeService.getPath(originatingLocation), true);
|
||||
String[] displayPathElements = displayPath.split(pathSeparator);
|
||||
Object[] subPath = ArrayUtils.subarray(displayPathElements, 5, displayPathElements.length);
|
||||
StringBuffer originatingLocationPath = new StringBuffer();
|
||||
for (int i = 0; i < subPath.length; i++)
|
||||
{
|
||||
originatingLocationPath.append(pathSeparator).append(subPath[i]);
|
||||
}
|
||||
rootJSONObject.put("originatingLocationPath", originatingLocationPath.toString());
|
||||
originatingLocationPath.append(pathSeparator).append(subPath[i]);
|
||||
}
|
||||
rootJSONObject.put("originatingLocationPath", originatingLocationPath.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -29,6 +29,7 @@ import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
|
||||
import org.alfresco.repo.policy.annotation.Behaviour;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourBean;
|
||||
import org.alfresco.repo.policy.annotation.BehaviourKind;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -78,27 +79,26 @@ public class VitalRecordDefinitionAspect extends BaseBehaviourBean
|
||||
kind = BehaviourKind.CLASS,
|
||||
notificationFrequency = NotificationFrequency.TRANSACTION_COMMIT
|
||||
)
|
||||
public void onUpdateProperties(final NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
|
||||
public void onUpdateProperties(final NodeRef nodeRef, final Map<QName, Serializable> before, final Map<QName, Serializable> after)
|
||||
{
|
||||
if (nodeService.exists(nodeRef) &&
|
||||
nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT))
|
||||
AuthenticationUtil.runAsSystem(new RunAsWork<Void>()
|
||||
{
|
||||
// check that vital record definition has been changed in the first place
|
||||
Map<QName, Serializable> changedProps = PropertyMap.getChangedProperties(before, after);
|
||||
if (changedProps.containsKey(PROP_VITAL_RECORD_INDICATOR) ||
|
||||
changedProps.containsKey(PROP_REVIEW_PERIOD))
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
filePlanAuthenticationService.runAsRmAdmin(new RunAsWork<Void>()
|
||||
if (nodeService.exists(nodeRef) &&
|
||||
nodeService.hasAspect(nodeRef, ASPECT_FILE_PLAN_COMPONENT))
|
||||
{
|
||||
@Override
|
||||
public Void doWork() throws Exception
|
||||
// check that vital record definition has been changed in the first place
|
||||
Map<QName, Serializable> changedProps = PropertyMap.getChangedProperties(before, after);
|
||||
if (changedProps.containsKey(PROP_VITAL_RECORD_INDICATOR) ||
|
||||
changedProps.containsKey(PROP_REVIEW_PERIOD))
|
||||
{
|
||||
recordsManagementActionService.executeRecordsManagementAction(nodeRef, "broadcastVitalRecordDefinition");
|
||||
return null;
|
||||
}}
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,228 @@
|
||||
|
||||
package org.alfresco.module.org_alfresco_module_rm.security;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sf.acegisecurity.AccessDeniedException;
|
||||
import net.sf.acegisecurity.intercept.InterceptorStatusToken;
|
||||
import net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor;
|
||||
import net.sf.acegisecurity.vote.AccessDecisionVoter;
|
||||
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Records Management Method Security Interceptor.
|
||||
* <p>
|
||||
* Provides a way to record information about the capabilities being executed and report
|
||||
* when an access denied exception is thrown.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
* @since 2.2
|
||||
*/
|
||||
public class RMMethodSecurityInterceptor extends MethodSecurityInterceptor
|
||||
{
|
||||
/** logger */
|
||||
protected static Log logger = LogFactory.getLog(RMMethodSecurityInterceptor.class);
|
||||
|
||||
/**
|
||||
* Helper class to hold capability report information
|
||||
*/
|
||||
private static class CapabilityReport
|
||||
{
|
||||
public String name;
|
||||
public AccessStatus status;
|
||||
public Map<String, Boolean> conditions = new HashMap<String, Boolean>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to translate vote to access status.
|
||||
*
|
||||
* @param vote vote
|
||||
* @return {@link AccessStatus} access status
|
||||
*/
|
||||
private static AccessStatus translate(int vote)
|
||||
{
|
||||
switch (vote)
|
||||
{
|
||||
case AccessDecisionVoter.ACCESS_ABSTAIN:
|
||||
return AccessStatus.UNDETERMINED;
|
||||
case AccessDecisionVoter.ACCESS_GRANTED:
|
||||
return AccessStatus.ALLOWED;
|
||||
case AccessDecisionVoter.ACCESS_DENIED:
|
||||
return AccessStatus.DENIED;
|
||||
default:
|
||||
return AccessStatus.UNDETERMINED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Current capability report details.
|
||||
* <p>
|
||||
* Used to getnerate the capability error report.
|
||||
*/
|
||||
private static final ThreadLocal<Map<String, CapabilityReport>> capabilities = new ThreadLocal<Map<String, CapabilityReport>>()
|
||||
{
|
||||
@Override
|
||||
protected Map<String, CapabilityReport> initialValue()
|
||||
{
|
||||
return new HashMap<String, CapabilityReport>();
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get capability report object from the thread local, creating one for
|
||||
* the given capability name if one does not already exist.
|
||||
*
|
||||
* @param name capability name
|
||||
* @return {@link CapabilityReport} object containing information about the capability
|
||||
*/
|
||||
private static final CapabilityReport getCapabilityReport(String name)
|
||||
{
|
||||
Map<String, CapabilityReport> map = RMMethodSecurityInterceptor.capabilities.get();
|
||||
CapabilityReport capability = map.get(name);
|
||||
if (capability == null)
|
||||
{
|
||||
capability = new CapabilityReport();
|
||||
capability.name = name;
|
||||
|
||||
map.put(name, capability);
|
||||
}
|
||||
return capability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report capability status.
|
||||
*
|
||||
* @param name capability name
|
||||
* @param status capability status
|
||||
*/
|
||||
public static void reportCapabilityStatus(String name, int status)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
CapabilityReport capability = getCapabilityReport(name);
|
||||
capability.status = translate(status);;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report capability condition.
|
||||
*
|
||||
* @param name capability name
|
||||
* @param conditionName capability condition name
|
||||
* @param expected expected value
|
||||
* @param actual actual value
|
||||
*/
|
||||
public static void reportCapabilityCondition(String name, String conditionName, boolean expected, boolean actual)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
CapabilityReport capability = getCapabilityReport(name);
|
||||
if (expected == false)
|
||||
{
|
||||
conditionName = "!" + conditionName;
|
||||
}
|
||||
capability.conditions.put(conditionName, (expected == actual));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the failure report for the currently recorded capabilities.
|
||||
*
|
||||
* @return {@link String} capability error report
|
||||
*/
|
||||
public String getFailureReport()
|
||||
{
|
||||
String result = null;
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
Collection<CapabilityReport> capabilities = RMMethodSecurityInterceptor.capabilities.get().values();
|
||||
|
||||
if (!capabilities.isEmpty())
|
||||
{
|
||||
StringBuffer buffer = new StringBuffer("\n");
|
||||
for (CapabilityReport capability : capabilities)
|
||||
{
|
||||
buffer.append(" ").append(capability.name).append(" (").append(capability.status).append(")\n");
|
||||
if (!capability.conditions.isEmpty())
|
||||
{
|
||||
for (Map.Entry<String, Boolean> entry : capability.conditions.entrySet())
|
||||
{
|
||||
buffer.append(" - ").append(entry.getKey()).append(" (");
|
||||
if (entry.getValue() == true)
|
||||
{
|
||||
buffer.append("passed");
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.append("failed");
|
||||
}
|
||||
buffer.append(")\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see net.sf.acegisecurity.intercept.AbstractSecurityInterceptor#beforeInvocation(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
protected InterceptorStatusToken beforeInvocation(Object object)
|
||||
{
|
||||
InterceptorStatusToken result = null;
|
||||
try
|
||||
{
|
||||
// clear the capability report information
|
||||
RMMethodSecurityInterceptor.capabilities.remove();
|
||||
|
||||
result = super.beforeInvocation(object);
|
||||
}
|
||||
catch (AccessDeniedException exception)
|
||||
{
|
||||
String failureReport = getFailureReport();
|
||||
if (failureReport == null)
|
||||
{
|
||||
throw exception;
|
||||
}
|
||||
else
|
||||
{
|
||||
// rethrow with additional information
|
||||
throw new AccessDeniedException(exception.getMessage() + getFailureReport(), exception);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
|
||||
*/
|
||||
@Override
|
||||
public Object invoke(MethodInvocation mi) throws Throwable
|
||||
{
|
||||
Object result = null;
|
||||
InterceptorStatusToken token = beforeInvocation(mi);
|
||||
|
||||
try
|
||||
{
|
||||
result = mi.proceed();
|
||||
}
|
||||
finally
|
||||
{
|
||||
result = super.afterInvocation(token, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user