Merged V2.2 to HEAD

7251: First cut at permissions checking in AVM


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8232 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-02-08 16:30:11 +00:00
parent 9fe73fc97c
commit 840b3e45be
10 changed files with 491 additions and 115 deletions

View File

@@ -75,6 +75,12 @@
<property name="avmLockingAwareService"> <property name="avmLockingAwareService">
<ref bean="avmLockingAwareService"/> <ref bean="avmLockingAwareService"/>
</property> </property>
<property name="avmRepository">
<ref bean="avmRepository"/>
</property>
<property name="permissionService">
<ref bean="permissionService"/>
</property>
</bean> </bean>
<!-- Bootstrap AVM Locking Service. --> <!-- Bootstrap AVM Locking Service. -->

View File

@@ -241,4 +241,10 @@ public interface AVMNode
* @param properties The properties to add. * @param properties The properties to add.
*/ */
public void addProperties(Map<QName, PropertyValue> properties); public void addProperties(Map<QName, PropertyValue> properties);
/**
* Get the Basic Attributes on this node.
* @return
*/
public BasicAttributes getBasicAttributes();
} }

View File

@@ -26,6 +26,7 @@ package org.alfresco.repo.avm;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@@ -37,6 +38,7 @@ import java.util.SortedMap;
import org.alfresco.repo.content.ContentStore; import org.alfresco.repo.content.ContentStore;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.avm.AVMBadArgumentException; import org.alfresco.service.cmr.avm.AVMBadArgumentException;
import org.alfresco.service.cmr.avm.AVMCycleException; import org.alfresco.service.cmr.avm.AVMCycleException;
@@ -51,10 +53,15 @@ import org.alfresco.service.cmr.avm.VersionDescriptor;
import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/** /**
* This or AVMStore are * This or AVMStore are
@@ -108,6 +115,10 @@ public class AVMRepository
private ChildEntryDAO fChildEntryDAO; private ChildEntryDAO fChildEntryDAO;
private PermissionService fPermissionService;
private ApplicationContext fContext;
// A bunch of TransactionListeners that do work for this. // A bunch of TransactionListeners that do work for this.
/** /**
@@ -224,6 +235,11 @@ public class AVMRepository
fChildEntryDAO = dao; fChildEntryDAO = dao;
} }
public void setPermissionService(PermissionService service)
{
fPermissionService = service;
}
/** /**
* Create a file. * Create a file.
* @param path The path to the containing directory. * @param path The path to the containing directory.
@@ -318,6 +334,10 @@ public class AVMRepository
{ {
throw new AVMWrongTypeException("Not a directory."); throw new AVMWrongTypeException("Not a directory.");
} }
if (!can(node, PermissionService.CREATE_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write in: " + parent);
}
// We need the store to do anything so... // We need the store to do anything so...
String [] pathParts = SplitPath(parent.getPath()); String [] pathParts = SplitPath(parent.getPath());
AVMStore store = getAVMStoreByName(pathParts[0]); AVMStore store = getAVMStoreByName(pathParts[0]);
@@ -338,6 +358,8 @@ public class AVMRepository
child = new PlainDirectoryNodeImpl(store); child = new PlainDirectoryNodeImpl(store);
} }
dir.putChild(name, child); dir.putChild(name, child);
DbAccessControlList acl = dir.getAcl();
child.setAcl(acl != null ? acl.getCopy() : null);
fLookupCache.onWrite(pathParts[0]); fLookupCache.onWrite(pathParts[0]);
AVMNodeDescriptor desc = child.getDescriptor(parent.getPath(), name, parent.getIndirection(), parent.getIndirectionVersion()); AVMNodeDescriptor desc = child.getDescriptor(parent.getPath(), name, parent.getIndirection(), parent.getIndirectionVersion());
return desc; return desc;
@@ -480,6 +502,10 @@ public class AVMRepository
throw new AVMNotFoundException("Path not found."); throw new AVMNotFoundException("Path not found.");
} }
DirectoryNode dirNode = (DirectoryNode)dPath.getCurrentNode(); DirectoryNode dirNode = (DirectoryNode)dPath.getCurrentNode();
if (!can(dirNode, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not permitted to add children: " + dstPath);
}
AVMNode srcNode = sPath.getCurrentNode(); AVMNode srcNode = sPath.getCurrentNode();
AVMNode dstNode = null; AVMNode dstNode = null;
// We do different things depending on what kind of thing we're // We do different things depending on what kind of thing we're
@@ -507,6 +533,8 @@ public class AVMRepository
dstNode.setAncestor(srcNode); dstNode.setAncestor(srcNode);
dirNode.putChild(name, dstNode); dirNode.putChild(name, dstNode);
dirNode.updateModTime(); dirNode.updateModTime();
DbAccessControlList acl = srcNode.getAcl();
dstNode.setAcl(acl != null ? acl.getCopy() : null);
String beginingPath = AVMNodeConverter.NormalizePath(srcPath); String beginingPath = AVMNodeConverter.NormalizePath(srcPath);
String finalPath = AVMNodeConverter.ExtendAVMPath(dstPath, name); String finalPath = AVMNodeConverter.ExtendAVMPath(dstPath, name);
finalPath = AVMNodeConverter.NormalizePath(finalPath); finalPath = AVMNodeConverter.NormalizePath(finalPath);
@@ -641,6 +669,10 @@ public class AVMRepository
throw new AVMNotFoundException("Path not found."); throw new AVMNotFoundException("Path not found.");
} }
srcDir = (DirectoryNode)sPath.getCurrentNode(); srcDir = (DirectoryNode)sPath.getCurrentNode();
if (!can(srcDir, PermissionService.DELETE_CHILDREN) || !can(srcDir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read or write: " + srcPath);
}
Pair<AVMNode, Boolean> temp = srcDir.lookupChild(sPath, srcName, false); Pair<AVMNode, Boolean> temp = srcDir.lookupChild(sPath, srcName, false);
srcNode = (temp == null) ? null : temp.getFirst(); srcNode = (temp == null) ? null : temp.getFirst();
if (srcNode == null) if (srcNode == null)
@@ -668,6 +700,10 @@ public class AVMRepository
throw new AVMNotFoundException("Path not found."); throw new AVMNotFoundException("Path not found.");
} }
DirectoryNode dstDir = (DirectoryNode)dPath.getCurrentNode(); DirectoryNode dstDir = (DirectoryNode)dPath.getCurrentNode();
if (!can(dstDir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write: " + dstPath);
}
Pair<AVMNode, Boolean> temp = dstDir.lookupChild(dPath, dstName, true); Pair<AVMNode, Boolean> temp = dstDir.lookupChild(dPath, dstName, true);
AVMNode child = (temp == null) ? null : temp.getFirst(); AVMNode child = (temp == null) ? null : temp.getFirst();
if (child != null && child.getType() != AVMNodeType.DELETED_NODE) if (child != null && child.getType() != AVMNodeType.DELETED_NODE)
@@ -864,6 +900,11 @@ public class AVMRepository
} }
fLookupCache.onDelete(name); fLookupCache.onDelete(name);
AVMNode root = store.getRoot(); AVMNode root = store.getRoot();
// TODO Probably a special PermissionService.PURGE is needed.
if (!can(root, PermissionService.DELETE_CHILDREN))
{
throw new AccessDeniedException("Not allowed to purge: " + name);
}
root.setIsRoot(false); root.setIsRoot(false);
List<VersionRoot> vRoots = fVersionRootDAO.getAllInAVMStore(store); List<VersionRoot> vRoots = fVersionRootDAO.getAllInAVMStore(store);
for (VersionRoot vr : vRoots) for (VersionRoot vr : vRoots)
@@ -934,6 +975,10 @@ public class AVMRepository
{ {
throw new AVMWrongTypeException(desc + " is not a File."); throw new AVMWrongTypeException(desc + " is not a File.");
} }
if (!can(node, PermissionService.READ_CONTENT))
{
throw new AccessDeniedException("Not allowed to read content: " + desc);
}
FileNode file = (FileNode)node; FileNode file = (FileNode)node;
ContentData data = file.getContentData(null); ContentData data = file.getContentData(null);
if (data == null) if (data == null)
@@ -1011,6 +1056,10 @@ public class AVMRepository
{ {
throw new AVMBadArgumentException("Invalid Node."); throw new AVMBadArgumentException("Invalid Node.");
} }
if (!can(node, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read children: " + dir);
}
if (node.getType() == AVMNodeType.PLAIN_DIRECTORY) if (node.getType() == AVMNodeType.PLAIN_DIRECTORY)
{ {
return getListing(dir, includeDeleted); return getListing(dir, includeDeleted);
@@ -1043,6 +1092,10 @@ public class AVMRepository
{ {
throw new AVMWrongTypeException("Not a directory."); throw new AVMWrongTypeException("Not a directory.");
} }
if (!can(node, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read children: " + dir);
}
DirectoryNode dirNode = (DirectoryNode)node; DirectoryNode dirNode = (DirectoryNode)node;
SortedMap<String, AVMNodeDescriptor> listing = dirNode.getListing(dir, includeDeleted); SortedMap<String, AVMNodeDescriptor> listing = dirNode.getListing(dir, includeDeleted);
return listing; return listing;
@@ -1305,6 +1358,10 @@ public class AVMRepository
throw new AVMWrongTypeException("Not a directory."); throw new AVMWrongTypeException("Not a directory.");
} }
DirectoryNode dirNode = (DirectoryNode)node; DirectoryNode dirNode = (DirectoryNode)node;
if (!can(dirNode, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read children: " + dir);
}
return dirNode.lookupChild(dir, name, includeDeleted); return dirNode.lookupChild(dir, name, includeDeleted);
} }
finally finally
@@ -1323,7 +1380,7 @@ public class AVMRepository
AVMNode node = fAVMNodeDAO.getByID(desc.getId()); AVMNode node = fAVMNodeDAO.getByID(desc.getId());
if (node == null) if (node == null)
{ {
throw new AVMNotFoundException("Not found: " + desc.getPath()); throw new AVMNotFoundException("Not found: " + desc);
} }
List<Pair<Integer, String>> paths = new ArrayList<Pair<Integer, String>>(); List<Pair<Integer, String>> paths = new ArrayList<Pair<Integer, String>>();
List<String> components = new ArrayList<String>(); List<String> components = new ArrayList<String>();
@@ -1389,6 +1446,10 @@ public class AVMRepository
*/ */
private void recursiveGetVersionPaths(AVMNode node, List<String> components, List<String> paths, DirectoryNode root, String storeName) private void recursiveGetVersionPaths(AVMNode node, List<String> components, List<String> paths, DirectoryNode root, String storeName)
{ {
if (!can(node, PermissionService.READ_CHILDREN))
{
return;
}
if (node.equals(root)) if (node.equals(root))
{ {
paths.add(this.makePath(components, storeName)); paths.add(this.makePath(components, storeName));
@@ -1422,7 +1483,7 @@ public class AVMRepository
AVMNode node = fAVMNodeDAO.getByID(desc.getId()); AVMNode node = fAVMNodeDAO.getByID(desc.getId());
if (node == null) if (node == null)
{ {
throw new AVMNotFoundException("Not found: " + desc.getPath()); throw new AVMNotFoundException("Not found: " + desc);
} }
List<Pair<Integer, String>> paths = new ArrayList<Pair<Integer, String>>(); List<Pair<Integer, String>> paths = new ArrayList<Pair<Integer, String>>();
List<String> components = new ArrayList<String>(); List<String> components = new ArrayList<String>();
@@ -1439,6 +1500,10 @@ public class AVMRepository
private void recursiveGetPaths(AVMNode node, List<String> components, private void recursiveGetPaths(AVMNode node, List<String> components,
List<Pair<Integer, String>> paths) List<Pair<Integer, String>> paths)
{ {
if (!can(node, PermissionService.READ_CHILDREN))
{
return;
}
if (node.getIsRoot()) if (node.getIsRoot())
{ {
AVMStore store = fAVMStoreDAO.getByRoot(node); AVMStore store = fAVMStoreDAO.getByRoot(node);
@@ -1472,6 +1537,10 @@ public class AVMRepository
*/ */
private Pair<Integer, String> recursiveGetAPath(AVMNode node, List<String> components) private Pair<Integer, String> recursiveGetAPath(AVMNode node, List<String> components)
{ {
if (!can(node, PermissionService.READ_CHILDREN))
{
return null;
}
if (node.getIsRoot()) if (node.getIsRoot())
{ {
AVMStore store = fAVMStoreDAO.getByRoot(node); AVMStore store = fAVMStoreDAO.getByRoot(node);
@@ -1510,6 +1579,10 @@ public class AVMRepository
private void recursiveGetHeadPaths(AVMNode node, List<String> components, private void recursiveGetHeadPaths(AVMNode node, List<String> components,
List<Pair<Integer, String>> paths) List<Pair<Integer, String>> paths)
{ {
if (!can(node, PermissionService.READ_CHILDREN))
{
return;
}
if (node.getIsRoot()) if (node.getIsRoot())
{ {
AVMStore store = fAVMStoreDAO.getByRoot(node); AVMStore store = fAVMStoreDAO.getByRoot(node);
@@ -1541,6 +1614,10 @@ public class AVMRepository
List<Pair<Integer, String>> paths, DirectoryNode root, List<Pair<Integer, String>> paths, DirectoryNode root,
String storeName) String storeName)
{ {
if (!can(node, PermissionService.READ_CHILDREN))
{
return;
}
if (node.equals(root)) if (node.equals(root))
{ {
addPath(components, -1, storeName, paths); addPath(components, -1, storeName, paths);
@@ -1628,6 +1705,10 @@ public class AVMRepository
{ {
throw new AVMNotFoundException("Path not found."); throw new AVMNotFoundException("Path not found.");
} }
if (!can(lookup.getCurrentNode(), PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + path);
}
return new LayeringDescriptor(!lookup.getDirectlyContained(), return new LayeringDescriptor(!lookup.getDirectlyContained(),
lookup.getAVMStore().getDescriptor(), lookup.getAVMStore().getDescriptor(),
lookup.getFinalStore().getDescriptor()); lookup.getFinalStore().getDescriptor());
@@ -1752,6 +1833,10 @@ public class AVMRepository
{ {
throw new AVMNotFoundException("Not found."); throw new AVMNotFoundException("Not found.");
} }
if (!can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + desc);
}
if (count < 0) if (count < 0)
{ {
count = Integer.MAX_VALUE; count = Integer.MAX_VALUE;
@@ -1764,6 +1849,10 @@ public class AVMRepository
{ {
break; break;
} }
if (!can(node, PermissionService.READ_PROPERTIES))
{
break;
}
history.add(node.getDescriptor("UNKNOWN", "UNKNOWN", "UNKNOWN", -1)); history.add(node.getDescriptor("UNKNOWN", "UNKNOWN", "UNKNOWN", -1));
} }
return history; return history;
@@ -2022,7 +2111,7 @@ public class AVMRepository
} }
/** /**
* Queries all AVM stores for properties with keys that matcha given pattern. * Queries all AVM stores for properties with keys that match a given pattern.
* @param keyPattern The sql 'like' pattern, inserted into a QName. * @param keyPattern The sql 'like' pattern, inserted into a QName.
* @return A List of Pairs of Store name, Map.Entry. * @return A List of Pairs of Store name, Map.Entry.
*/ */
@@ -2102,6 +2191,16 @@ public class AVMRepository
{ {
throw new AVMNotFoundException("Node not found."); throw new AVMNotFoundException("Node not found.");
} }
if (!can(lNode, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + left);
}
if (!can(rNode, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + right);
}
// TODO Short changing the permissions checking here. I'm not sure
// if that's OK.
List<AVMNode> leftHistory = new ArrayList<AVMNode>(); List<AVMNode> leftHistory = new ArrayList<AVMNode>();
List<AVMNode> rightHistory = new ArrayList<AVMNode>(); List<AVMNode> rightHistory = new ArrayList<AVMNode>();
while (lNode != null || rNode != null) while (lNode != null || rNode != null)
@@ -2429,6 +2528,7 @@ public class AVMRepository
} }
} }
/** /**
* This is the danger version of link. It must be called on * This is the danger version of link. It must be called on
* a copied and unsnapshotted directory. It blithely inserts * a copied and unsnapshotted directory. It blithely inserts
@@ -2449,6 +2549,10 @@ public class AVMRepository
{ {
throw new AVMException("Directory has not already been copied."); throw new AVMException("Directory has not already been copied.");
} }
if (!can(dir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write: " + parent);
}
dir.link(name, child); dir.link(name, child);
} }
@@ -2480,6 +2584,10 @@ public class AVMRepository
{ {
throw new AVMWrongTypeException("Not a Layered Directory."); throw new AVMWrongTypeException("Not a Layered Directory.");
} }
if (!can(node, PermissionService.DELETE_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write in: " + path);
}
LayeredDirectoryNode dir = (LayeredDirectoryNode)node; LayeredDirectoryNode dir = (LayeredDirectoryNode)node;
dir.flatten(name); dir.flatten(name);
} }
@@ -2661,7 +2769,7 @@ public class AVMRepository
AVMNode node = fAVMNodeDAO.getByID(desc.getId()); AVMNode node = fAVMNodeDAO.getByID(desc.getId());
if (node == null) if (node == null)
{ {
throw new AVMNotFoundException("Not found: " + desc.getPath()); throw new AVMNotFoundException("Not found: " + desc);
} }
List<String> paths = new ArrayList<String>(); List<String> paths = new ArrayList<String>();
List<String> components = new ArrayList<String>(); List<String> components = new ArrayList<String>();
@@ -2678,6 +2786,10 @@ public class AVMRepository
private void recursiveGetStoreVersionPaths(String storeName, AVMNode node, int version, List<String> components, private void recursiveGetStoreVersionPaths(String storeName, AVMNode node, int version, List<String> components,
List<String> paths) List<String> paths)
{ {
if (!can(node, PermissionService.READ))
{
return;
}
if (node.getIsRoot()) if (node.getIsRoot())
{ {
VersionRoot versionRoot = fVersionRootDAO.getByRoot(node); VersionRoot versionRoot = fVersionRootDAO.getByRoot(node);
@@ -2707,6 +2819,10 @@ public class AVMRepository
{ {
throw new AVMNotFoundException("Node not found: " + desc); throw new AVMNotFoundException("Node not found: " + desc);
} }
if (!can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + desc);
}
return node.getProperties(); return node.getProperties();
} }
@@ -2717,6 +2833,10 @@ public class AVMRepository
{ {
throw new AVMNotFoundException("Node not found: " + desc); throw new AVMNotFoundException("Node not found: " + desc);
} }
if (!can(node, PermissionService.READ_CONTENT))
{
throw new AccessDeniedException("Not allowed to read: " + desc);
}
if (node.getType() == AVMNodeType.PLAIN_FILE) if (node.getType() == AVMNodeType.PLAIN_FILE)
{ {
PlainFileNode file = (PlainFileNode)node; PlainFileNode file = (PlainFileNode)node;
@@ -2732,7 +2852,40 @@ public class AVMRepository
{ {
throw new AVMNotFoundException("Node not found: " + desc); throw new AVMNotFoundException("Node not found: " + desc);
} }
if (!can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + desc);
}
Set<QName> aspects = node.getAspects(); Set<QName> aspects = node.getAspects();
return aspects; return aspects;
} }
/**
* Evaluate permission on a node.
* I've got a bad feeling about this...
* @param node
* @param permission
* @return
*/
public boolean can(AVMNode node, String permission)
{
DbAccessControlList acl = node.getAcl();
if (acl == null)
{
return true;
}
Map<String, Object> context = new HashMap<String, Object>(4);
context.put(PermissionService.OWNER_AUTHORITY, node.getBasicAttributes().getOwner());
context.put(PermissionService.ASPECTS, node.getAspects());
Map<QName, PropertyValue> props = node.getProperties();
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(5);
for (Map.Entry<QName, PropertyValue> entry : props.entrySet())
{
properties.put(entry.getKey(), entry.getValue().getValue(entry.getKey()));
}
context.put(PermissionService.PROPERTIES, properties);
// TODO put node type in there to.
return fPermissionService.hasPermission(acl.getId(), context, permission)
== AccessStatus.ALLOWED;
}
} }

View File

@@ -42,6 +42,7 @@ import org.alfresco.repo.avm.util.RawServices;
import org.alfresco.repo.avm.util.SimplePath; import org.alfresco.repo.avm.util.SimplePath;
import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.DbAccessControlList;
import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.avm.AVMBadArgumentException; import org.alfresco.service.cmr.avm.AVMBadArgumentException;
import org.alfresco.service.cmr.avm.AVMException; import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMExistsException; import org.alfresco.service.cmr.avm.AVMExistsException;
@@ -57,6 +58,7 @@ import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
@@ -327,6 +329,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true); Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true);
AVMNode child = (temp == null) ? null : temp.getFirst(); AVMNode child = (temp == null) ? null : temp.getFirst();
if (child != null && child.getType() != AVMNodeType.DELETED_NODE) if (child != null && child.getType() != AVMNodeType.DELETED_NODE)
@@ -361,6 +367,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
newDir.getProperties().putAll(properties); newDir.getProperties().putAll(properties);
} }
DbAccessControlList acl = dir.getAcl();
newDir.setAcl(acl != null ? acl.getCopy() : null);
} }
/** /**
@@ -422,6 +430,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true); Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true);
AVMNode child = (temp == null) ? null : temp.getFirst(); AVMNode child = (temp == null) ? null : temp.getFirst();
if (child != null && child.getType() != AVMNodeType.DELETED_NODE) if (child != null && child.getType() != AVMNodeType.DELETED_NODE)
@@ -440,6 +452,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
RawServices.Instance().getMimetypeService().guessMimetype(name), RawServices.Instance().getMimetypeService().guessMimetype(name),
-1, -1,
"UTF-8")); "UTF-8"));
DbAccessControlList acl = dir.getAcl();
file.setAcl(acl != null ? acl.getCopy() : null);
ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name)); ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name));
return writer.getContentOutputStream(); return writer.getContentOutputStream();
} }
@@ -458,6 +472,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true); Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true);
AVMNode child = (temp == null) ? null : temp.getFirst(); AVMNode child = (temp == null) ? null : temp.getFirst();
if (child != null && child.getType() != AVMNodeType.DELETED_NODE) if (child != null && child.getType() != AVMNodeType.DELETED_NODE)
@@ -484,6 +502,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
file.getProperties().putAll(properties); file.getProperties().putAll(properties);
} }
DbAccessControlList acl = dir.getAcl();
file.setAcl(acl != null ? acl.getCopy() : null);
// Yet another flush. // Yet another flush.
AVMDAOs.Instance().fAVMNodeDAO.flush(); AVMDAOs.Instance().fAVMNodeDAO.flush();
ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name)); ContentWriter writer = createContentWriter(AVMNodeConverter.ExtendAVMPath(path, name));
@@ -504,6 +524,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + dstPath + " not found."); throw new AVMNotFoundException("Path " + dstPath + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write: " + dstPath);
}
Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true); Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true);
AVMNode child = (temp == null) ? null : temp.getFirst(); AVMNode child = (temp == null) ? null : temp.getFirst();
if (child != null && child.getType() != AVMNodeType.DELETED_NODE) if (child != null && child.getType() != AVMNodeType.DELETED_NODE)
@@ -519,6 +543,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
dir.updateModTime(); dir.updateModTime();
dir.putChild(name, newFile); dir.putChild(name, newFile);
DbAccessControlList acl = dir.getAcl();
newFile.setAcl(acl != null ? acl.getCopy() : null);
// newFile.setVersionID(getNextVersionID()); // newFile.setVersionID(getNextVersionID());
} }
@@ -580,6 +606,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read: " + path);
}
Map<String, AVMNode> listing = dir.getListing(lPath, includeDeleted); Map<String, AVMNode> listing = dir.getListing(lPath, includeDeleted);
return translateListing(listing, lPath); return translateListing(listing, lPath);
} }
@@ -599,6 +629,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read: " + path);
}
if (lPath.isLayered() && dir.getType() != AVMNodeType.LAYERED_DIRECTORY) if (lPath.isLayered() && dir.getType() != AVMNodeType.LAYERED_DIRECTORY)
{ {
return new TreeMap<String, AVMNodeDescriptor>(); return new TreeMap<String, AVMNodeDescriptor>();
@@ -642,6 +676,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read: " + path);
}
List<String> deleted = dir.getDeletedNames(); List<String> deleted = dir.getDeletedNames();
return deleted; return deleted;
} }
@@ -670,14 +708,16 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.DELETE_CHILDREN))
{
throw new AVMNotFoundException("Not allowed to write: " + path);
}
if (dir.lookupChild(lPath, name, false) == null) if (dir.lookupChild(lPath, name, false) == null)
{ {
throw new AVMNotFoundException("Does not exist: " + name); throw new AVMNotFoundException("Does not exist: " + name);
} }
dir.removeChild(lPath, name); dir.removeChild(lPath, name);
dir.updateModTime(); dir.updateModTime();
// AVMDAOs.Instance().fAVMNodeDAO.flush();
// AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
} }
/** /**
@@ -697,6 +737,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMWrongTypeException("Not a layered directory: " + dirPath); throw new AVMWrongTypeException("Not a layered directory: " + dirPath);
} }
if (!fAVMRepository.can(node, PermissionService.DELETE_CHILDREN))
{
throw new AccessDeniedException("Not allowed to write: " + dirPath);
}
((LayeredDirectoryNode)node).uncover(lPath, name); ((LayeredDirectoryNode)node).uncover(lPath, name);
node.updateModTime(); node.updateModTime();
} }
@@ -792,6 +836,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
root = AVMDAOs.Instance().fAVMNodeDAO.getAVMStoreRoot(this, version); root = AVMDAOs.Instance().fAVMNodeDAO.getAVMStoreRoot(this, version);
} }
if (!fAVMRepository.can(root, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read: " + fName + "@" + version);
}
return root.getDescriptor(fName + ":", "", null, -1); return root.getDescriptor(fName + ":", "", null, -1);
} }
@@ -837,6 +885,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
return null; return null;
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read: " + path);
}
if (node.getType() == AVMNodeType.LAYERED_DIRECTORY) if (node.getType() == AVMNodeType.LAYERED_DIRECTORY)
{ {
LayeredDirectoryNode dir = (LayeredDirectoryNode)node; LayeredDirectoryNode dir = (LayeredDirectoryNode)node;
@@ -866,6 +918,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMException("Not in a layered context: " + path); throw new AVMException("Not in a layered context: " + path);
} }
if (!fAVMRepository.can(dir, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
dir.turnPrimary(lPath); dir.turnPrimary(lPath);
dir.updateModTime(); dir.updateModTime();
} }
@@ -887,6 +943,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMException("Not in a layered context: " + path); throw new AVMException("Not in a layered context: " + path);
} }
if (!fAVMRepository.can(dir, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
dir.retarget(lPath, target); dir.retarget(lPath, target);
dir.updateModTime(); dir.updateModTime();
} }
@@ -1018,6 +1078,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(vRoot); AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.delete(vRoot);
AVMNode root = vRoot.getRoot(); AVMNode root = vRoot.getRoot();
if (!fAVMRepository.can(root, PermissionService.DELETE_CHILDREN))
{
throw new AccessDeniedException("Not allowed to purge: " + fName + "@" + version);
}
root.setIsRoot(false); root.setIsRoot(false);
AVMDAOs.Instance().fAVMNodeDAO.update(root); AVMDAOs.Instance().fAVMNodeDAO.update(root);
AVMDAOs.Instance().fVersionRootDAO.delete(vRoot); AVMDAOs.Instance().fVersionRootDAO.delete(vRoot);
@@ -1031,6 +1095,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
} }
} }
// TODO permissions?
/** /**
* Get the descriptor for this. * Get the descriptor for this.
* @return An AVMStoreDescriptor * @return An AVMStoreDescriptor
@@ -1060,6 +1125,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMWrongTypeException("Not a LayeredDirectoryNode."); throw new AVMWrongTypeException("Not a LayeredDirectoryNode.");
} }
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
((LayeredDirectoryNode)node).setOpacity(opacity); ((LayeredDirectoryNode)node).setOpacity(opacity);
node.updateModTime(); node.updateModTime();
} }
@@ -1079,6 +1148,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
node.setProperty(name, value); node.setProperty(name, value);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
} }
@@ -1096,6 +1169,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
node.addProperties(properties); node.addProperties(properties);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
} }
@@ -1115,6 +1192,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read: " + path);
}
PropertyValue prop = node.getProperty(name); PropertyValue prop = node.getProperty(name);
return prop; return prop;
} }
@@ -1133,6 +1214,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read: " + path);
}
Map<QName, PropertyValue> props = node.getProperties(); Map<QName, PropertyValue> props = node.getProperties();
return props; return props;
} }
@@ -1150,6 +1235,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
node.deleteProperty(name); node.deleteProperty(name);
} }
@@ -1166,6 +1255,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
node.deleteProperties(); node.deleteProperties();
} }
@@ -1254,6 +1347,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMWrongTypeException("File Expected."); throw new AVMWrongTypeException("File Expected.");
} }
if (!fAVMRepository.can(node, PermissionService.READ_CONTENT))
{
throw new AccessDeniedException("Not allowed to read: " + path);
}
ContentData content = ((FileNode)node).getContentData(lPath); ContentData content = ((FileNode)node).getContentData(lPath);
// AVMDAOs.Instance().fAVMNodeDAO.flush(); // AVMDAOs.Instance().fAVMNodeDAO.flush();
// AVMDAOs.Instance().fAVMNodeDAO.evict(node); // AVMDAOs.Instance().fAVMNodeDAO.evict(node);
@@ -1277,6 +1374,11 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMWrongTypeException("File Expected."); throw new AVMWrongTypeException("File Expected.");
} }
if (!fAVMRepository.can(node, PermissionService.WRITE_CONTENT))
{
throw new AccessDeniedException("Not allowed to write content: " + path);
}
// TODO Set modifier.
node.updateModTime(); node.updateModTime();
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
ContentData content = ((FileNode)node).getContentData(lPath); ContentData content = ((FileNode)node).getContentData(lPath);
@@ -1285,6 +1387,8 @@ public class AVMStoreImpl implements AVMStore, Serializable
return content; return content;
} }
// Not doing permission checking because it will already have been done
// at the getContentDataForWrite point.
/** /**
* Set the ContentData for a file. * Set the ContentData for a file.
* @param path The path to the file. * @param path The path to the file.
@@ -1318,6 +1422,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path not found: " + path); throw new AVMNotFoundException("Path not found: " + path);
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write properties: " + path);
}
node.copyMetaDataFrom(from); node.copyMetaDataFrom(from);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
} }
@@ -1335,6 +1443,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write: " + path);
}
node.getAspects().add(aspectName); node.getAspects().add(aspectName);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
} }
@@ -1353,6 +1465,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + path);
}
Set<QName> aspects = node.getAspects(); Set<QName> aspects = node.getAspects();
return aspects; return aspects;
} }
@@ -1370,6 +1486,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write properties: " + path);
}
node.getAspects().remove(aspectName); node.getAspects().remove(aspectName);
AspectDefinition def = RawServices.Instance().getDictionaryService().getAspect(aspectName); AspectDefinition def = RawServices.Instance().getDictionaryService().getAspect(aspectName);
Map<QName, PropertyDefinition> properties = Map<QName, PropertyDefinition> properties =
@@ -1396,6 +1516,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.READ_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to read properties: " + path);
}
boolean has = node.getAspects().contains(aspectName); boolean has = node.getAspects().contains(aspectName);
return has; return has;
} }
@@ -1413,6 +1537,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.CHANGE_PERMISSIONS))
{
throw new AccessDeniedException("Not allowed to change permissions: " + path);
}
node.setAcl(acl); node.setAcl(acl);
node.setGuid(GUID.generate()); node.setGuid(GUID.generate());
} }
@@ -1430,6 +1558,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
if (!fAVMRepository.can(lPath.getCurrentNode(), PermissionService.READ_PERMISSIONS))
{
throw new AccessDeniedException("Not allowed to read permissions: " + path);
}
return lPath.getCurrentNode().getAcl(); return lPath.getCurrentNode().getAcl();
} }
@@ -1447,9 +1579,11 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + parentPath + " not found."); throw new AVMNotFoundException("Path " + parentPath + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to add children: " + parentPath);
}
dir.link(lPath, name, toLink); dir.link(lPath, name, toLink);
//AVMDAOs.Instance().fAVMNodeDAO.flush();
//AVMDAOs.Instance().fAVMNodeDAO.evict(dir);
} }
/** /**
@@ -1468,6 +1602,11 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path " + path + " not found."); throw new AVMNotFoundException("Path " + path + " not found.");
} }
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
if (!fAVMRepository.can(dir, PermissionService.DELETE_CHILDREN) ||
!fAVMRepository.can(dir, PermissionService.ADD_CHILDREN))
{
throw new AccessDeniedException("Not allowed to revert: " + path);
}
Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true); Pair<AVMNode, Boolean> temp = dir.lookupChild(lPath, name, true);
AVMNode child = (temp == null) ? null : temp.getFirst(); AVMNode child = (temp == null) ? null : temp.getFirst();
if (child == null) if (child == null)
@@ -1500,6 +1639,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
throw new AVMNotFoundException("Path not found: " + path); throw new AVMNotFoundException("Path not found: " + path);
} }
AVMNode node = lPath.getCurrentNode(); AVMNode node = lPath.getCurrentNode();
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write properties: " + path);
}
node.setGuid(guid); node.setGuid(guid);
} }
@@ -1518,6 +1661,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMWrongTypeException("Not a File: " + path); throw new AVMWrongTypeException("Not a File: " + path);
} }
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write properties: " + path);
}
PlainFileNode file = (PlainFileNode)node; PlainFileNode file = (PlainFileNode)node;
file.setEncoding(encoding); file.setEncoding(encoding);
} }
@@ -1537,6 +1684,10 @@ public class AVMStoreImpl implements AVMStore, Serializable
{ {
throw new AVMWrongTypeException("Not a File: " + path); throw new AVMWrongTypeException("Not a File: " + path);
} }
if (!fAVMRepository.can(node, PermissionService.WRITE_PROPERTIES))
{
throw new AccessDeniedException("Not allowed to write properties: " + path);
}
PlainFileNode file = (PlainFileNode)node; PlainFileNode file = (PlainFileNode)node;
file.setMimeType(mimeType); file.setMimeType(mimeType);
} }

View File

@@ -27,6 +27,7 @@ package org.alfresco.repo.avm;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.AbstractLifecycleBean; import org.alfresco.util.AbstractLifecycleBean;
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEvent;
@@ -46,6 +47,10 @@ public class AvmBootstrap extends AbstractLifecycleBean
private AVMLockingAwareService avmLockingAwareService; private AVMLockingAwareService avmLockingAwareService;
private AVMRepository avmRepository;
private PermissionService permissionService;
public AvmBootstrap() public AvmBootstrap()
{ {
issuers = new ArrayList<Issuer>(0); issuers = new ArrayList<Issuer>(0);
@@ -56,6 +61,16 @@ public class AvmBootstrap extends AbstractLifecycleBean
avmLockingAwareService = service; avmLockingAwareService = service;
} }
public void setAvmRepository(AVMRepository repository)
{
avmRepository = repository;
}
public void setPermissionService(PermissionService service)
{
permissionService = service;
}
/** /**
* Provide a list of {@link Issuer issuers} to bootstrap on context initialization. * Provide a list of {@link Issuer issuers} to bootstrap on context initialization.
* *
@@ -77,6 +92,7 @@ public class AvmBootstrap extends AbstractLifecycleBean
issuer.initialize(); issuer.initialize();
} }
avmLockingAwareService.init(); avmLockingAwareService.init();
avmRepository.setPermissionService(permissionService);
} }
/** NO-OP */ /** NO-OP */

View File

@@ -8,6 +8,8 @@ import java.util.List;
import org.alfresco.repo.avm.util.SimplePath; import org.alfresco.repo.avm.util.SimplePath;
import org.alfresco.repo.cache.SimpleCache; import org.alfresco.repo.cache.SimpleCache;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -107,7 +109,10 @@ public class LookupCache
else else
{ {
VersionRoot vRoot = AVMDAOs.Instance().fVersionRootDAO.getByVersionID(store, version); VersionRoot vRoot = AVMDAOs.Instance().fVersionRootDAO.getByVersionID(store, version);
if (vRoot != null)
{
dir = vRoot.getRoot(); dir = vRoot.getRoot();
}
// dir = fAVMNodeDAO.getAVMStoreRoot(store, version); // dir = fAVMNodeDAO.getAVMStoreRoot(store, version);
} }
if (dir == null) if (dir == null)
@@ -127,6 +132,10 @@ public class LookupCache
// before the end. // before the end.
for (int i = 0; i < path.size() - 1; i++) for (int i = 0; i < path.size() - 1; i++)
{ {
if (!AVMRepository.GetInstance().can(dir, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read children: " + path.get(i));
}
Pair<AVMNode, Boolean> child = dir.lookupChild(result, path.get(i), includeDeleted); Pair<AVMNode, Boolean> child = dir.lookupChild(result, path.get(i), includeDeleted);
if (child == null) if (child == null)
{ {
@@ -142,6 +151,10 @@ public class LookupCache
dir = (DirectoryNode)result.getCurrentNode(); dir = (DirectoryNode)result.getCurrentNode();
} }
// Now look up the last element. // Now look up the last element.
if (!AVMRepository.GetInstance().can(dir, PermissionService.READ_CHILDREN))
{
throw new AccessDeniedException("Not allowed to read children: " + path.get(path.size() - 1));
}
Pair<AVMNode, Boolean> child = dir.lookupChild(result, path.get(path.size() - 1), Pair<AVMNode, Boolean> child = dir.lookupChild(result, path.get(path.size() - 1),
includeDeleted); includeDeleted);
if (child == null) if (child == null)

View File

@@ -12,7 +12,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.remote.ClientTicketHolder; import org.alfresco.repo.remote.ClientTicketHolder;
import org.alfresco.repo.remote.ClientTicketHolderGlobal;
import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.remote.AVMRemote; import org.alfresco.service.cmr.remote.AVMRemote;
import org.alfresco.service.cmr.remote.RepoRemote; import org.alfresco.service.cmr.remote.RepoRemote;
@@ -65,7 +64,7 @@ public abstract class CltBase
*/ */
protected CltBase() protected CltBase()
{ {
fContext = new ClassPathXmlApplicationContext("alfresco/clt-context.xml"); fContext = new ClassPathXmlApplicationContext("clt-context.xml");
fAVMRemote = (AVMRemote)fContext.getBean("avmRemote"); fAVMRemote = (AVMRemote)fContext.getBean("avmRemote");
fAVMSyncService = (AVMSyncService)fContext.getBean("avmSyncService"); fAVMSyncService = (AVMSyncService)fContext.getBean("avmSyncService");
fRepoRemote = (RepoRemote)fContext.getBean("repoRemote"); fRepoRemote = (RepoRemote)fContext.getBean("repoRemote");

View File

@@ -396,6 +396,16 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
return status; return status;
} }
/* (non-Javadoc)
* @see org.alfresco.service.cmr.security.PermissionService#hasPermission(java.lang.Long, java.lang.String, java.lang.String)
*/
public AccessStatus hasPermission(Long aclID, Map<String, Object> context,
String permission)
{
// TODO Implement.
return AccessStatus.ALLOWED;
}
enum CacheType enum CacheType
{ {
HAS_PERMISSION, SINGLE_PERMISSION, SINGLE_PERMISSION_GLOBAL; HAS_PERMISSION, SINGLE_PERMISSION, SINGLE_PERMISSION_GLOBAL;
@@ -716,7 +726,6 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
if (checkGlobalPermissions(authorisations) || checkRequired(authorisations, nodeRef, locallyDenied)) if (checkGlobalPermissions(authorisations) || checkRequired(authorisations, nodeRef, locallyDenied))
{ {
// No need to do the recursive test as it has been found // No need to do the recursive test as it has been found
recursiveOut = null;
if (recursiveIn != null) if (recursiveIn != null)
{ {
recursiveIn.setValue(true); recursiveIn.setValue(true);

View File

@@ -217,6 +217,15 @@ public class PermissionServiceNOOPImpl
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/* (non-Javadoc)
* @see org.alfresco.service.cmr.security.PermissionService#hasPermission(java.lang.Long, java.lang.String, java.lang.String)
*/
public AccessStatus hasPermission(Long aclID, Map<String, Object> context,
String permission)
{
return AccessStatus.ALLOWED;
}
public void setPermission(NodePermissionEntry nodePermissionEntry) public void setPermission(NodePermissionEntry nodePermissionEntry)
{ {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@@ -149,6 +149,10 @@ public interface PermissionService
public static final String CANCEL_CHECK_OUT = "CancelCheckOut"; public static final String CANCEL_CHECK_OUT = "CancelCheckOut";
public static final String ASPECTS = "Aspects";
public static final String PROPERTIES = "Properties";
/** /**
* Get the Owner Authority * Get the Owner Authority
* *
@@ -222,6 +226,16 @@ public interface PermissionService
@Auditable(key = Auditable.Key.ARG_0, parameters = { "nodeRef", "permission" }) @Auditable(key = Auditable.Key.ARG_0, parameters = { "nodeRef", "permission" })
public AccessStatus hasPermission(NodeRef nodeRef, String permission); public AccessStatus hasPermission(NodeRef nodeRef, String permission);
/**
* Check if a permission is allowed on an acl.
* @param aclID
* @param owner
* @param permission
* @return
*/
@Auditable(parameters = { "aclID", "context", "permission" })
public AccessStatus hasPermission(Long aclID, Map<String, Object> context, String permission);
/** /**
* Delete all the permission assigned to the node * Delete all the permission assigned to the node
* *