mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
RM-523: Installation: Impossible to install RM module without -force option
* overriden file removed from both AMPs * alternative solution found for hard coded "read" permission checks * build scripts updated to remove --force parameter * MMT dependancies updated (need to grab these from Maven at some point if possible) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/modules/recordsmanagement/BRANCHES/V2.0@42779 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -301,7 +301,7 @@ subprojects {
|
||||
|
||||
mmt = new org.alfresco.repo.module.tool.ModuleManagementTool()
|
||||
mmt.setVerbose(true)
|
||||
mmt.installModule(ampFileLocation.getPath(), warFileLocation.getPath(), false, true, false)
|
||||
mmt.installModule(ampFileLocation.getPath(), warFileLocation.getPath(), false, false, false)
|
||||
}
|
||||
|
||||
task cleanDeploy(type: Delete) {
|
||||
|
Binary file not shown.
BIN
mmt/commons-compress-1.4.jar
Normal file
BIN
mmt/commons-compress-1.4.jar
Normal file
Binary file not shown.
BIN
mmt/truezip-driver-file-7.5.5.jar
Normal file
BIN
mmt/truezip-driver-file-7.5.5.jar
Normal file
Binary file not shown.
BIN
mmt/truezip-driver-zip-7.5.5.jar
Normal file
BIN
mmt/truezip-driver-zip-7.5.5.jar
Normal file
Binary file not shown.
BIN
mmt/truezip-file-7.5.5.jar
Normal file
BIN
mmt/truezip-file-7.5.5.jar
Normal file
Binary file not shown.
BIN
mmt/truezip-kernel-7.5.5.jar
Normal file
BIN
mmt/truezip-kernel-7.5.5.jar
Normal file
Binary file not shown.
BIN
mmt/truezip-swing-7.5.5.jar
Normal file
BIN
mmt/truezip-swing-7.5.5.jar
Normal file
Binary file not shown.
BIN
mmt/xz-1.0.jar
Normal file
BIN
mmt/xz-1.0.jar
Normal file
Binary file not shown.
@@ -1,264 +0,0 @@
|
||||
const REQUEST_MAX = 1000;
|
||||
|
||||
/**
|
||||
* Main entry point: Create collection of documents and folders in the given space
|
||||
*
|
||||
* @method doclist_main
|
||||
*/
|
||||
function doclist_main()
|
||||
{
|
||||
// Use helper function to get the arguments
|
||||
var parsedArgs = ParseArgs.getParsedArgs();
|
||||
if (parsedArgs === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var filter = args.filter,
|
||||
items = [];
|
||||
|
||||
// Try to find a filter query based on the passed-in arguments
|
||||
var allNodes = [],
|
||||
totalRecords = 0,
|
||||
requestTotalCountMax = 0,
|
||||
paged = false,
|
||||
favourites = Common.getFavourites(),
|
||||
filterParams = Filters.getFilterParams(filter, parsedArgs,
|
||||
{
|
||||
favourites: favourites
|
||||
}),
|
||||
query = filterParams.query;
|
||||
|
||||
if ((filter || "path") == "path")
|
||||
{
|
||||
// TODO also add DB filter by "node" (in addition to "path")
|
||||
var parentNode = parsedArgs.pathNode;
|
||||
if (parentNode !== null)
|
||||
{
|
||||
var skip = -1,
|
||||
max = -1;
|
||||
|
||||
if (args.size != null)
|
||||
{
|
||||
max = args.size;
|
||||
|
||||
if (args.pos > 0)
|
||||
{
|
||||
skip = (args.pos - 1) * max;
|
||||
}
|
||||
}
|
||||
|
||||
var sortField = (args.sortField == null ? "cm:name" : args.sortField),
|
||||
sortAsc = (((args.sortAsc == null) || (args.sortAsc == "true")) ? true : false);
|
||||
|
||||
// Get paged set
|
||||
requestTotalCountMax = skip + REQUEST_MAX;
|
||||
var pagedResult = parentNode.childFileFolders(true, true, filterParams.ignoreTypes, skip, max, requestTotalCountMax, sortField, sortAsc, "TODO");
|
||||
|
||||
allNodes = pagedResult.page;
|
||||
totalRecords = pagedResult.totalResultCountUpper;
|
||||
paged = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Query the nodes - passing in sort and result limit parameters
|
||||
if (query !== "")
|
||||
{
|
||||
allNodes = search.query(
|
||||
{
|
||||
query: query,
|
||||
language: filterParams.language,
|
||||
page:
|
||||
{
|
||||
maxItems: (filterParams.limitResults ? parseInt(filterParams.limitResults, 10) : 0)
|
||||
},
|
||||
sort: filterParams.sort,
|
||||
templates: filterParams.templates,
|
||||
namespace: (filterParams.namespace ? filterParams.namespace : null)
|
||||
});
|
||||
|
||||
totalRecords = allNodes.length;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure folders and folderlinks appear at the top of the list
|
||||
var folderNodes = [],
|
||||
documentNodes = [];
|
||||
|
||||
for each (node in allNodes)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (node.isContainer || node.isLinkToContainer)
|
||||
{
|
||||
folderNodes.push(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
documentNodes.push(node);
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// Possibly an old indexed node - ignore it
|
||||
}
|
||||
}
|
||||
|
||||
// Node type counts
|
||||
var folderNodesCount = folderNodes.length,
|
||||
documentNodesCount = documentNodes.length,
|
||||
nodes;
|
||||
|
||||
if (parsedArgs.type === "documents")
|
||||
{
|
||||
nodes = documentNodes;
|
||||
totalRecords -= folderNodesCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Sorting with folders at end -- swap order of concat()
|
||||
nodes = folderNodes.concat(documentNodes);
|
||||
}
|
||||
|
||||
// Pagination
|
||||
var pageSize = args.size || nodes.length,
|
||||
pagePos = args.pos || "1",
|
||||
startIndex = (pagePos - 1) * pageSize;
|
||||
|
||||
if (!paged)
|
||||
{
|
||||
// Trim the nodes array down to the page size
|
||||
nodes = nodes.slice(startIndex, pagePos * pageSize);
|
||||
}
|
||||
|
||||
// Common or variable parent container?
|
||||
var parent = null;
|
||||
|
||||
if (!filterParams.variablePath)
|
||||
{
|
||||
// Parent node permissions (and Site role if applicable)
|
||||
parent = Evaluator.run(parsedArgs.pathNode, true);
|
||||
}
|
||||
|
||||
var isThumbnailNameRegistered = thumbnailService.isThumbnailNameRegistered(THUMBNAIL_NAME),
|
||||
thumbnail = null,
|
||||
locationNode,
|
||||
item;
|
||||
|
||||
// Loop through and evaluate each node in this result set
|
||||
for each (node in nodes)
|
||||
{
|
||||
// Get evaluated properties.
|
||||
item = Evaluator.run(node);
|
||||
if (item !== null)
|
||||
{
|
||||
item.isFavourite = (favourites[item.node.nodeRef] === true);
|
||||
item.likes = Common.getLikes(node);
|
||||
|
||||
// Does this collection of nodes have potentially differering paths?
|
||||
if (filterParams.variablePath || item.isLink)
|
||||
{
|
||||
locationNode = item.isLink ? item.linkedNode : item.node;
|
||||
location = Common.getLocation(locationNode, parsedArgs.libraryRoot);
|
||||
// Parent node
|
||||
if (node.parent != null &&
|
||||
(node.parent.hasPermission("Read") || node.parent.hasPermission("ReadRecords")))
|
||||
{
|
||||
item.parent = Evaluator.run(node.parent, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
location =
|
||||
{
|
||||
site: parsedArgs.location.site,
|
||||
siteTitle: parsedArgs.location.siteTitle,
|
||||
sitePreset: parsedArgs.location.sitePreset,
|
||||
container: parsedArgs.location.container,
|
||||
containerType: parsedArgs.location.containerType,
|
||||
path: parsedArgs.location.path,
|
||||
file: node.name
|
||||
};
|
||||
}
|
||||
|
||||
// Resolved location
|
||||
item.location = location;
|
||||
|
||||
// Check: thumbnail type is registered && node is a cm:content subtype && valid inputStream for content property
|
||||
if (isThumbnailNameRegistered && item.node.isSubType("cm:content") && item.node.properties.content.inputStream != null)
|
||||
{
|
||||
// Make sure we have a thumbnail.
|
||||
thumbnail = item.node.getThumbnail(THUMBNAIL_NAME);
|
||||
if (thumbnail === null)
|
||||
{
|
||||
// No thumbnail, so queue creation
|
||||
item.node.createThumbnail(THUMBNAIL_NAME, true);
|
||||
}
|
||||
}
|
||||
|
||||
items.push(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
--totalRecords;
|
||||
}
|
||||
}
|
||||
|
||||
// Array Remove - By John Resig (MIT Licensed)
|
||||
var fnArrayRemove = function fnArrayRemove(array, from, to)
|
||||
{
|
||||
var rest = array.slice((to || from) + 1 || array.length);
|
||||
array.length = from < 0 ? array.length + from : from;
|
||||
return array.push.apply(array, rest);
|
||||
};
|
||||
|
||||
/**
|
||||
* De-duplicate orignals for any existing working copies.
|
||||
* This can't be done in evaluator.lib.js as it has no knowledge of the current filter or UI operation.
|
||||
* Note: This may result in pages containing less than the configured amount of items (50 by default).
|
||||
*/
|
||||
for each (item in items)
|
||||
{
|
||||
if (item.workingCopy.isWorkingCopy)
|
||||
{
|
||||
var workingCopySource = String(item.workingCopy.sourceNodeRef);
|
||||
for (var i = 0, ii = items.length; i < ii; i++)
|
||||
{
|
||||
if (String(items[i].node.nodeRef) == workingCopySource)
|
||||
{
|
||||
fnArrayRemove(items, i);
|
||||
--totalRecords;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var paging =
|
||||
{
|
||||
totalRecords: totalRecords,
|
||||
startIndex: startIndex
|
||||
};
|
||||
|
||||
if (paged && (totalRecords == requestTotalCountMax))
|
||||
{
|
||||
paging.totalRecordsUpper = requestTotalCountMax;
|
||||
}
|
||||
|
||||
return (
|
||||
{
|
||||
luceneQuery: query,
|
||||
paging: paging,
|
||||
container: parsedArgs.rootNode,
|
||||
parent: parent,
|
||||
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
|
||||
itemCount:
|
||||
{
|
||||
folders: folderNodesCount,
|
||||
documents: documentNodesCount
|
||||
},
|
||||
items: items,
|
||||
customJSON: slingshotDocLib.getJSON()
|
||||
});
|
||||
}
|
@@ -1,77 +0,0 @@
|
||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/evaluator.lib.js">
|
||||
<import resource="classpath:/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary-v2/parse-args.lib.js">
|
||||
|
||||
/**
|
||||
* Main entry point: Return single document or folder given it's nodeRef
|
||||
*
|
||||
* @method getDoclist
|
||||
*/
|
||||
function getDoclist()
|
||||
{
|
||||
// Use helper function to get the arguments
|
||||
var parsedArgs = ParseArgs.getParsedArgs();
|
||||
if (parsedArgs === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
parsedArgs.pathNode = ParseArgs.resolveNode(parsedArgs.nodeRef);
|
||||
parsedArgs.location = Common.getLocation(parsedArgs.pathNode, parsedArgs.libraryRoot);
|
||||
|
||||
var favourites = Common.getFavourites(),
|
||||
node = parsedArgs.pathNode;
|
||||
|
||||
var isThumbnailNameRegistered = thumbnailService.isThumbnailNameRegistered(THUMBNAIL_NAME),
|
||||
thumbnail = null,
|
||||
item = Evaluator.run(node);
|
||||
|
||||
item.isFavourite = (favourites[node.nodeRef] === true);
|
||||
item.likes = Common.getLikes(node);
|
||||
item.location =
|
||||
{
|
||||
site: parsedArgs.location.site,
|
||||
siteTitle: parsedArgs.location.siteTitle,
|
||||
container: parsedArgs.location.container,
|
||||
containerType: parsedArgs.location.containerType,
|
||||
path: parsedArgs.location.path,
|
||||
file: node.name
|
||||
};
|
||||
|
||||
item.parent = {};
|
||||
if (node.parent != null && (node.parent.hasPermission("Read") || node.parent.hasPermission("ReadRecords")))
|
||||
{
|
||||
item.parent = Evaluator.run(node.parent, true);
|
||||
}
|
||||
|
||||
// Special case for container and libraryRoot nodes
|
||||
if ((parsedArgs.location.containerNode && String(parsedArgs.location.containerNode.nodeRef) == String(node.nodeRef)) ||
|
||||
(parsedArgs.libraryRoot && String(parsedArgs.libraryRoot.nodeRef) == String(node.nodeRef)))
|
||||
{
|
||||
item.location.file = "";
|
||||
}
|
||||
|
||||
// Check: thumbnail type is registered && node is a cm:content subtype && valid inputStream for content property
|
||||
if (isThumbnailNameRegistered && item.node.isSubType("cm:content") && item.node.properties.content.inputStream != null)
|
||||
{
|
||||
// Make sure we have a thumbnail.
|
||||
thumbnail = item.node.getThumbnail(THUMBNAIL_NAME);
|
||||
if (thumbnail === null)
|
||||
{
|
||||
// No thumbnail, so queue creation
|
||||
item.node.createThumbnail(THUMBNAIL_NAME, true);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
{
|
||||
container: parsedArgs.rootNode,
|
||||
onlineEditing: utils.moduleInstalled("org.alfresco.module.vti"),
|
||||
item: item,
|
||||
customJSON: slingshotDocLib.getJSON()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Document List Component: doclist
|
||||
*/
|
||||
model.doclist = getDoclist();
|
@@ -1,370 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -32,6 +32,7 @@ import net.sf.acegisecurity.providers.dao.User;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.capability.RMPermissionModel;
|
||||
import org.alfresco.module.org_alfresco_module_rm.model.RecordsManagementModel;
|
||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.repo.avm.AVMRepository;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
@@ -82,6 +83,10 @@ import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
|
||||
/**
|
||||
* Currently required to re-implement the permission service.
|
||||
*
|
||||
* As of V4.2 this will no longer be required.
|
||||
*
|
||||
* @author Roy Wetherall
|
||||
*/
|
||||
public class PermissionServiceImpl extends AbstractLifecycleBean implements PermissionServiceSPI
|
||||
@@ -1037,9 +1042,31 @@ public class PermissionServiceImpl extends AbstractLifecycleBean implements Perm
|
||||
deletePermission(nodeRef, authority, getPermissionReference(perm));
|
||||
}
|
||||
|
||||
public AccessStatus hasPermission(NodeRef nodeRef, String perm)
|
||||
public AccessStatus hasPermission(final NodeRef nodeRef, final String perm)
|
||||
{
|
||||
return hasPermission(nodeRef, getPermissionReference(perm));
|
||||
// NOTE: this is a work around fix for the specific case when we are asking if a filePlan node has
|
||||
// READ permission, but in fact this makes no sense and we mean ReadRecord
|
||||
//
|
||||
// For now we will restrict this change to only this form of the method to limit the
|
||||
// potential effects. When this is refactored to extend the updated PermissionService post 4.2
|
||||
// it can be readdressed and determined if there is a better place for this.
|
||||
String updatedPerm = AuthenticationUtil.runAsSystem(new RunAsWork<String>()
|
||||
{
|
||||
@Override
|
||||
public String doWork() throws Exception
|
||||
{
|
||||
String result = perm;
|
||||
if ("Read".equals(perm) == true &&
|
||||
nodeService.hasAspect(nodeRef, RecordsManagementModel.ASPECT_FILE_PLAN_COMPONENT) == true)
|
||||
{
|
||||
result = "ReadRecords";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return hasPermission(nodeRef, getPermissionReference(updatedPerm));
|
||||
}
|
||||
|
||||
public void setPermission(NodeRef nodeRef, String authority, String perm, boolean allow)
|
||||
|
Reference in New Issue
Block a user