mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-477: RM 2.0 does not work with SOLR
* first pass at supporting SOLR in RM2 * currently requires reimplementation of permissionServiceImpl due to visibility of methods and member variables * job execution delayed to try and prevent start up errors * fetchSOLR task added to gradle to retrieve SOLR zip from Maven (could do with some scripts to help with setup for module) * TODO more testing and refinement of solution git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0-BUG-FIX@40344 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -239,6 +239,13 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
task localisationPackage (type: Copy) << {
|
||||
|
||||
from configDir
|
||||
include "**/*.properties"
|
||||
into "${assembleDir}/i18n"
|
||||
}
|
||||
|
||||
task deployExploded(dependsOn: 'jar') << {
|
||||
|
||||
def jarFileObj = file(jarFilePath)
|
||||
|
@@ -13,6 +13,17 @@ dependencies {
|
||||
testRuntime files(testResourceDir)
|
||||
|
||||
testRuntime group: 'org.alfresco.enterprise', name: 'alfresco', version: alfrescoBaseVersion, type: 'war'
|
||||
testRuntime group: 'org.alfresco.enterprise', name: 'alfresco-solr', version: alfrescoBaseVersion, type: 'zip'
|
||||
}
|
||||
|
||||
task fetchSOLR(type:Copy) {
|
||||
from configurations.testRuntime
|
||||
into '.'
|
||||
include '*.zip'
|
||||
rename { String filename -> solrFile }
|
||||
}
|
||||
|
||||
task useSOLR << {
|
||||
}
|
||||
|
||||
task resetDatabase << {
|
||||
|
@@ -2,6 +2,53 @@
|
||||
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||
|
||||
<beans>
|
||||
<bean id="permissionServiceImpl" class="org.alfresco.module.org_alfresco_module_rm.permission.PermissionServiceImpl" init-method="init">
|
||||
<property name="nodeService">
|
||||
<ref bean="mtAwareNodeService" />
|
||||
</property>
|
||||
<property name="tenantService">
|
||||
<ref bean="tenantService"/>
|
||||
</property>
|
||||
<property name="dictionaryService">
|
||||
<ref bean="dictionaryService" />
|
||||
</property>
|
||||
<property name="permissionsDaoComponent">
|
||||
<ref bean="permissionsDaoComponent" />
|
||||
</property>
|
||||
<property name="modelDAO">
|
||||
<ref bean="permissionsModelDAO" />
|
||||
</property>
|
||||
<property name="authorityService">
|
||||
<ref bean="authorityService" />
|
||||
</property>
|
||||
<property name="accessCache">
|
||||
<ref bean="permissionsAccessCache" />
|
||||
</property>
|
||||
<property name="readersCache">
|
||||
<ref bean="readersCache" />
|
||||
</property>
|
||||
<property name="readersDeniedCache">
|
||||
<ref bean="readersDeniedCache" />
|
||||
</property>
|
||||
<property name="policyComponent">
|
||||
<ref bean="policyComponent" />
|
||||
</property>
|
||||
<property name="aclDAO">
|
||||
<ref bean="aclDAO" />
|
||||
</property>
|
||||
<property name="ownableService">
|
||||
<ref bean="ownableService" />
|
||||
</property>
|
||||
<property name="anyDenyDenies">
|
||||
<value>${security.anyDenyDenies}</value>
|
||||
</property>
|
||||
<property name="dynamicAuthorities">
|
||||
<list>
|
||||
<ref bean="ownerDynamicAuthority" />
|
||||
<ref bean="lockOwnerDynamicAuthority" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Bootstrap records management data -->
|
||||
<bean id="org_alfresco_module_rm_bootstrapData"
|
||||
|
@@ -292,7 +292,7 @@
|
||||
{
|
||||
"name" : "Vital Records Due For Review",
|
||||
"description" : "All records currently due for review.",
|
||||
"search" : "reviewAsOf:[MIN TO TODAY]",
|
||||
"search" : "rma:reviewAsOf:[MIN TO TODAY]",
|
||||
"searchparams" :
|
||||
{
|
||||
"records" : true,
|
||||
|
@@ -3,5 +3,6 @@ moduleid=org_alfresco_module_rm
|
||||
|
||||
webAppName=alfresco
|
||||
warFile=alfresco.war
|
||||
solrFile=alfresco-solr.zip
|
||||
|
||||
tomcatEnv=TOMCAT_HOME
|
@@ -473,8 +473,11 @@ public class RMAfterInvocationProvider extends RMSecurityCommon
|
||||
{
|
||||
inclusionMask.set(i, true);
|
||||
}
|
||||
filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(returnedObject.getResultSetMetaData().getLimitedBy(), PermissionEvaluationMode.EAGER, returnedObject.getResultSetMetaData()
|
||||
.getSearchParameters()));
|
||||
filteringResultSet.setResultSetMetaData(
|
||||
new SimpleResultSetMetaData(
|
||||
returnedObject.getResultSetMetaData().getLimitedBy(),
|
||||
PermissionEvaluationMode.EAGER,
|
||||
returnedObject.getResultSetMetaData().getSearchParameters()));
|
||||
return filteringResultSet;
|
||||
}
|
||||
else
|
||||
@@ -483,27 +486,37 @@ public class RMAfterInvocationProvider extends RMSecurityCommon
|
||||
{
|
||||
inclusionMask.set(i, true);
|
||||
}
|
||||
filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(returnedObject.getResultSetMetaData().getLimitedBy(), PermissionEvaluationMode.EAGER, returnedObject.getResultSetMetaData()
|
||||
.getSearchParameters()));
|
||||
filteringResultSet.setResultSetMetaData(
|
||||
new SimpleResultSetMetaData(
|
||||
returnedObject.getResultSetMetaData().getLimitedBy(),
|
||||
PermissionEvaluationMode.EAGER,
|
||||
returnedObject.getResultSetMetaData().getSearchParameters()));
|
||||
return filteringResultSet;
|
||||
}
|
||||
}
|
||||
|
||||
// record the start time
|
||||
long startTimeMillis = System.currentTimeMillis();
|
||||
|
||||
// set the default, unlimited resultset type
|
||||
filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(returnedObject.getResultSetMetaData().getLimitedBy(), PermissionEvaluationMode.EAGER, returnedObject.getResultSetMetaData()
|
||||
.getSearchParameters()));
|
||||
filteringResultSet.setResultSetMetaData(
|
||||
new SimpleResultSetMetaData(
|
||||
returnedObject.getResultSetMetaData().getLimitedBy(),
|
||||
PermissionEvaluationMode.EAGER,
|
||||
returnedObject.getResultSetMetaData().getSearchParameters()));
|
||||
|
||||
for (int i = 0; i < returnedObject.length(); i++)
|
||||
{
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
if (i >= maxChecks || (currentTimeMillis - startTimeMillis) > maxCheckTime)
|
||||
{
|
||||
filteringResultSet.setResultSetMetaData(new SimpleResultSetMetaData(LimitBy.NUMBER_OF_PERMISSION_EVALUATIONS, PermissionEvaluationMode.EAGER, returnedObject
|
||||
.getResultSetMetaData().getSearchParameters()));
|
||||
break;
|
||||
}
|
||||
// if (i >= maxChecks || (currentTimeMillis - startTimeMillis) > maxCheckTime)
|
||||
// {
|
||||
// filteringResultSet.setResultSetMetaData(
|
||||
// new SimpleResultSetMetaData(
|
||||
// LimitBy.NUMBER_OF_PERMISSION_EVALUATIONS,
|
||||
// PermissionEvaluationMode.EAGER,
|
||||
// returnedObject.getResultSetMetaData().getSearchParameters()));
|
||||
// break;
|
||||
// }
|
||||
|
||||
// All permission checks must pass
|
||||
inclusionMask.set(i, true);
|
||||
|
@@ -106,13 +106,14 @@ public class RMSecurityCommon
|
||||
*/
|
||||
public int checkRead(NodeRef nodeRef)
|
||||
{
|
||||
int result = AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
if (nodeRef != null)
|
||||
{
|
||||
// now we know the node - we can abstain for certain types and aspects (eg, rm)
|
||||
return checkRead(nodeRef, false);
|
||||
result = checkRead(nodeRef, false);
|
||||
}
|
||||
|
||||
return AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,35 +124,32 @@ public class RMSecurityCommon
|
||||
*/
|
||||
public int checkRead(NodeRef nodeRef, boolean allowDMRead)
|
||||
{
|
||||
if (nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT))
|
||||
int result = AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
|
||||
if (rmService.isFilePlanComponent(nodeRef) == true)
|
||||
{
|
||||
return checkRmRead(nodeRef);
|
||||
result = checkRmRead(nodeRef);
|
||||
}
|
||||
else
|
||||
else if (allowDMRead == true)
|
||||
{
|
||||
if (allowDMRead)
|
||||
// Check DM read for copy etc
|
||||
// DM does not grant - it can only deny
|
||||
if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED)
|
||||
{
|
||||
// Check DM read for copy etc
|
||||
// DM does not grant - it can only deny
|
||||
if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED)
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\t\tPermission is denied");
|
||||
Thread.dumpStack();
|
||||
}
|
||||
return AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_GRANTED;
|
||||
logger.debug("\t\tPermission is denied");
|
||||
Thread.dumpStack();
|
||||
}
|
||||
result = AccessDecisionVoter.ACCESS_DENIED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AccessDecisionVoter.ACCESS_ABSTAIN;
|
||||
result = AccessDecisionVoter.ACCESS_GRANTED;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -72,7 +72,7 @@ public class DispositionLifecycleJobExecuter extends RecordsManagementJobExecute
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJobExecuter#execute()
|
||||
*/
|
||||
public void execute()
|
||||
public void executeImpl()
|
||||
{
|
||||
logger.debug("Job Starting");
|
||||
|
||||
|
@@ -69,7 +69,7 @@ public class NotifyOfRecordsDueForReviewJobExecuter extends RecordsManagementJob
|
||||
/**
|
||||
* @see org.alfresco.module.org_alfresco_module_rm.job.RecordsManagementJobExecuter#execute()
|
||||
*/
|
||||
public void execute()
|
||||
public void executeImpl()
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
|
@@ -80,7 +80,7 @@ public class PublishUpdatesJobExecuter extends RecordsManagementJobExecuter
|
||||
this.behaviourFilter = behaviourFilter;
|
||||
}
|
||||
|
||||
public void execute()
|
||||
public void executeImpl()
|
||||
{
|
||||
if (logger.isDebugEnabled() == true)
|
||||
{
|
||||
|
@@ -20,18 +20,73 @@ package org.alfresco.module.org_alfresco_module_rm.job;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
|
||||
/**
|
||||
* Records management job executer base class.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public abstract class RecordsManagementJobExecuter implements RecordsManagementModel
|
||||
public abstract class RecordsManagementJobExecuter extends AbstractLifecycleBean
|
||||
implements RecordsManagementModel
|
||||
{
|
||||
/** Retrying transaction helper */
|
||||
protected RetryingTransactionHelper retryingTransactionHelper;
|
||||
|
||||
/** Indicates whether the application bootstrap is complete or not */
|
||||
protected boolean bootstrapComplete = false;
|
||||
|
||||
/**
|
||||
* @param retryingTransactionHelper retrying transaction helper
|
||||
*/
|
||||
public void setRetryingTransactionHelper(RetryingTransactionHelper retryingTransactionHelper)
|
||||
{
|
||||
this.retryingTransactionHelper = retryingTransactionHelper;
|
||||
}
|
||||
|
||||
public abstract void execute();
|
||||
/**
|
||||
* Executes the jobs work.
|
||||
*/
|
||||
public void execute()
|
||||
{
|
||||
// jobs not allowed to execute unless bootstrap is complete
|
||||
if (bootstrapComplete == true)
|
||||
{
|
||||
executeImpl();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Jobs work implementation.
|
||||
*/
|
||||
public abstract void executeImpl();
|
||||
|
||||
/**
|
||||
* @see org.springframework.extensions.surf.util.AbstractLifecycleBean#onBootstrap(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent arg0)
|
||||
{
|
||||
// record that the bootstrap has complete
|
||||
bootstrapComplete = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.extensions.surf.util.AbstractLifecycleBean#onShutdown(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent arg0)
|
||||
{
|
||||
// no implementation
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.springframework.extensions.surf.util.AbstractLifecycleBean#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent arg0)
|
||||
{
|
||||
// no implementation
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,370 @@
|
||||
package org.alfresco.module.org_alfresco_module_rm.permission;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.repo.domain.permissions.AclDAO;
|
||||
import org.alfresco.repo.security.permissions.AccessControlEntry;
|
||||
import org.alfresco.repo.security.permissions.AccessControlList;
|
||||
import org.alfresco.repo.security.permissions.PermissionEntry;
|
||||
import org.alfresco.repo.security.permissions.PermissionReference;
|
||||
import org.alfresco.repo.security.permissions.impl.ModelDAO;
|
||||
import org.alfresco.repo.security.permissions.impl.PermissionServiceImpl;
|
||||
import org.alfresco.repo.security.permissions.impl.RequiredPermission;
|
||||
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
|
||||
import org.alfresco.service.cmr.security.AccessStatus;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
|
||||
public class OtherImpl extends PermissionServiceImpl
|
||||
{
|
||||
static SimplePermissionReference RM_OLD_ALL_PERMISSIONS_REFERENCE = SimplePermissionReference.getPermissionReference(
|
||||
QName.createQName("", PermissionService.ALL_PERMISSIONS),
|
||||
PermissionService.ALL_PERMISSIONS);
|
||||
|
||||
private SimpleCache<Serializable, Set<String>> rmReadersCache;
|
||||
|
||||
private AclDAO rmAclDaoComponent;
|
||||
|
||||
private ModelDAO rmModelDao;
|
||||
|
||||
public void setRmReadersCache(SimpleCache<Serializable, Set<String>> rmReadersCache)
|
||||
{
|
||||
this.rmReadersCache = rmReadersCache;
|
||||
}
|
||||
|
||||
public void setRmAclDAO(AclDAO rmAclDaoComponent)
|
||||
{
|
||||
this.rmAclDaoComponent = rmAclDaoComponent;
|
||||
}
|
||||
|
||||
public void setRmModelDAO(ModelDAO rmModelDao)
|
||||
{
|
||||
this.rmModelDao = rmModelDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnyDenyDenies(boolean anyDenyDenies)
|
||||
{
|
||||
super.setAnyDenyDenies(anyDenyDenies);
|
||||
rmReadersCache.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getReaders(Long aclId)
|
||||
{
|
||||
Set<String> dmReaders = super.getReaders(aclId);
|
||||
|
||||
Set<String> rmReaders = rmReadersCache.get(aclId);
|
||||
if (rmReaders == null)
|
||||
{
|
||||
rmReaders = buildRMReaders(aclId);
|
||||
rmReadersCache.put(aclId, rmReaders);
|
||||
}
|
||||
|
||||
Set<String> result = new HashSet<String>();
|
||||
result.addAll(dmReaders);
|
||||
result.addAll(rmReaders);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<String> buildRMReaders(Long aclId)
|
||||
{
|
||||
AccessControlList acl = rmAclDaoComponent.getAccessControlList(aclId);
|
||||
if (acl == null)
|
||||
{
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
HashSet<String> assigned = new HashSet<String>();
|
||||
HashSet<String> readers = new HashSet<String>();
|
||||
|
||||
for (AccessControlEntry ace : acl.getEntries())
|
||||
{
|
||||
assigned.add(ace.getAuthority());
|
||||
}
|
||||
|
||||
PermissionReference permissionRef = getPermissionReference(RMPermissionModel.READ_RECORDS);
|
||||
|
||||
for (String authority : assigned)
|
||||
{
|
||||
RMUnconditionalAclTest rmTest = new RMUnconditionalAclTest(permissionRef);
|
||||
if (rmTest.evaluate(authority, aclId))
|
||||
{
|
||||
readers.add(authority);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(readers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignores type and aspect requirements on the node
|
||||
*
|
||||
*/
|
||||
private class RMUnconditionalAclTest
|
||||
{
|
||||
/*
|
||||
* The required permission.
|
||||
*/
|
||||
PermissionReference required;
|
||||
|
||||
/*
|
||||
* Granters of the permission
|
||||
*/
|
||||
Set<PermissionReference> granters;
|
||||
|
||||
/*
|
||||
* The additional permissions required at the node level.
|
||||
*/
|
||||
Set<PermissionReference> nodeRequirements = new HashSet<PermissionReference>();
|
||||
|
||||
/*
|
||||
* Constructor just gets the additional requirements
|
||||
*/
|
||||
RMUnconditionalAclTest(PermissionReference required)
|
||||
{
|
||||
this.required = required;
|
||||
|
||||
// Set the required node permissions
|
||||
if (required.equals(getPermissionReference(ALL_PERMISSIONS)))
|
||||
{
|
||||
nodeRequirements = rmModelDao.getUnconditionalRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), RequiredPermission.On.NODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeRequirements = rmModelDao.getUnconditionalRequiredPermissions(required, RequiredPermission.On.NODE);
|
||||
}
|
||||
|
||||
if (rmModelDao.getUnconditionalRequiredPermissions(required, RequiredPermission.On.PARENT).size() > 0)
|
||||
{
|
||||
throw new IllegalStateException("Parent permissions can not be checked for an acl");
|
||||
}
|
||||
|
||||
if (rmModelDao.getUnconditionalRequiredPermissions(required, RequiredPermission.On.CHILDREN).size() > 0)
|
||||
{
|
||||
throw new IllegalStateException("Child permissions can not be checked for an acl");
|
||||
}
|
||||
|
||||
// Find all the permissions that grant the allowed permission
|
||||
// All permissions are treated specially.
|
||||
granters = new LinkedHashSet<PermissionReference>(128, 1.0f);
|
||||
granters.addAll(rmModelDao.getGrantingPermissions(required));
|
||||
granters.add(getAllPermissionReference());
|
||||
granters.add(RM_OLD_ALL_PERMISSIONS_REFERENCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal hook point for recursion
|
||||
*
|
||||
* @param authorisations
|
||||
* @param nodeRef
|
||||
* @param denied
|
||||
* @param recursiveIn
|
||||
* @return true if granted
|
||||
*/
|
||||
boolean evaluate(String authority, Long aclId)
|
||||
{
|
||||
// Start out true and "and" all other results
|
||||
boolean success = true;
|
||||
|
||||
// Check the required permissions but not for sets they rely on
|
||||
// their underlying permissions
|
||||
//if (modelDAO.checkPermission(required))
|
||||
//{
|
||||
|
||||
// We have to do the test as no parent will help us out
|
||||
success &= hasSinglePermission(authority, aclId);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//}
|
||||
|
||||
// Check the other permissions required on the node
|
||||
for (PermissionReference pr : nodeRequirements)
|
||||
{
|
||||
// Build a new test
|
||||
RMUnconditionalAclTest nt = new RMUnconditionalAclTest(pr);
|
||||
success &= nt.evaluate(authority, aclId);
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
boolean hasSinglePermission(String authority, Long aclId)
|
||||
{
|
||||
// Check global permission
|
||||
|
||||
if (checkGlobalPermissions(authority))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(aclId == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return checkRequired(authority, aclId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we have a global permission
|
||||
*
|
||||
* @param authorisations
|
||||
* @return true if granted
|
||||
*/
|
||||
private boolean checkGlobalPermissions(String authority)
|
||||
{
|
||||
for (PermissionEntry pe : rmModelDao.getGlobalPermissionEntries())
|
||||
{
|
||||
if (isGranted(pe, authority))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a given authentication is available on a node
|
||||
*
|
||||
* @param authorisations
|
||||
* @param nodeRef
|
||||
* @param denied
|
||||
* @return true if a check is required
|
||||
*/
|
||||
boolean checkRequired(String authority, Long aclId)
|
||||
{
|
||||
AccessControlList acl = rmAclDaoComponent.getAccessControlList(aclId);
|
||||
|
||||
if (acl == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Pair<String, PermissionReference>> denied = new HashSet<Pair<String, PermissionReference>>();
|
||||
|
||||
// Check if each permission allows - the first wins.
|
||||
// We could have other voting style mechanisms here
|
||||
for (AccessControlEntry ace : acl.getEntries())
|
||||
{
|
||||
if (isGranted(ace, authority, denied))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a permission granted
|
||||
*
|
||||
* @param pe -
|
||||
* the permissions entry to consider
|
||||
* @param granters -
|
||||
* the set of granters
|
||||
* @param authorisations -
|
||||
* the set of authorities
|
||||
* @param denied -
|
||||
* the set of denied permissions/authority pais
|
||||
* @return true if granted
|
||||
*/
|
||||
private boolean isGranted(AccessControlEntry ace, String authority, Set<Pair<String, PermissionReference>> denied)
|
||||
{
|
||||
// If the permission entry denies then we just deny
|
||||
if (ace.getAccessStatus() == AccessStatus.DENIED)
|
||||
{
|
||||
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), ace.getPermission()));
|
||||
|
||||
Set<PermissionReference> granters = rmModelDao.getGrantingPermissions(ace.getPermission());
|
||||
for (PermissionReference granter : granters)
|
||||
{
|
||||
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), granter));
|
||||
}
|
||||
|
||||
// All the things granted by this permission must be
|
||||
// denied
|
||||
Set<PermissionReference> grantees = rmModelDao.getGranteePermissions(ace.getPermission());
|
||||
for (PermissionReference grantee : grantees)
|
||||
{
|
||||
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), grantee));
|
||||
}
|
||||
|
||||
// All permission excludes all permissions available for
|
||||
// the node.
|
||||
if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(RM_OLD_ALL_PERMISSIONS_REFERENCE))
|
||||
{
|
||||
for (PermissionReference deny : rmModelDao.getAllPermissions())
|
||||
{
|
||||
denied.add(new Pair<String, PermissionReference>(ace.getAuthority(), deny));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The permission is allowed but we deny it as it is in the denied
|
||||
// set
|
||||
|
||||
if (denied != null)
|
||||
{
|
||||
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(ace.getAuthority(), required);
|
||||
if (denied.contains(specific))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If the permission has a match in both the authorities and
|
||||
// granters list it is allowed
|
||||
// It applies to the current user and it is granted
|
||||
if (authority.equals(ace.getAuthority()) && granters.contains(ace.getPermission()))
|
||||
{
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Default deny
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isGranted(PermissionEntry pe, String authority)
|
||||
{
|
||||
// If the permission entry denies then we just deny
|
||||
if (pe.isDenied())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the permission has a match in both the authorities and
|
||||
// granters list it is allowed
|
||||
// It applies to the current user and it is granted
|
||||
if (granters.contains(pe.getPermissionReference()) && authority.equals(pe.getAuthority()))
|
||||
{
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Default deny
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user