From db771f3113c5c940d2047c9e53812523638dc698 Mon Sep 17 00:00:00 2001 From: Steven Glover Date: Tue, 12 Oct 2010 09:04:36 +0000 Subject: [PATCH] Fix for ALF-1719: "Possibility to delete one of www,avm_webapps,ROOT folders" git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@23029 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/filesys/avm/AVMDiskDriver.java | 42 +++++++------ .../org/alfresco/filesys/avm/AVMPath.java | 62 +++++++++++++------ 2 files changed, 66 insertions(+), 38 deletions(-) diff --git a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java index 7bab2b1943..d96873246e 100644 --- a/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java +++ b/source/java/org/alfresco/filesys/avm/AVMDiskDriver.java @@ -1067,20 +1067,23 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface // Convert the relative path to a store path AVMContext ctx = (AVMContext) tree.getContext(); - final AVMPath storePath = buildStorePath(ctx, dir, sess); + + final String[] paths = FileName.splitPath(dir); + final AVMPath parentPath = buildStorePath(ctx, paths[0], sess); + final AVMPath dirPath = buildStorePath(ctx, dir, sess); // DEBUG if (logger.isDebugEnabled()) - logger.debug("Delete directory, path=" + dir + ", storePath=" + storePath); + logger.debug("Delete directory, path=" + dir + ", dirPath=" + dirPath); // Check if the filesystem is the virtualization view if (ctx.isVirtualizationView()) { - if (storePath.isPseudoPath()) + if (parentPath.isPseudoPath()) throw new AccessDeniedException("Cannot delete folder in store/version layer, " + dir); - else if ( storePath.isReadOnlyAccess()) + else if ( parentPath.isReadOnlyAccess()) throw new AccessDeniedException("Cannot delete folder " + dir + ", read-only path"); } @@ -1092,7 +1095,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface public Void call() throws IOException { - AVMNodeDescriptor nodeDesc = m_avmService.lookup(storePath.getVersion(), storePath.getAVMPath()); + AVMNodeDescriptor nodeDesc = m_avmService.lookup(dirPath.getVersion(), dirPath.getAVMPath()); if (nodeDesc != null) { // Check that we are deleting a folder @@ -1107,7 +1110,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface // Delete the folder - m_avmService.removeNode(storePath.getAVMPath()); + m_avmService.removeNode(dirPath.getAVMPath()); } else throw new IOException("Delete directory path is not a directory, " + dir); @@ -1146,20 +1149,23 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface // Convert the relative path to a store path AVMContext ctx = (AVMContext) tree.getContext(); - final AVMPath storePath = buildStorePath(ctx, name, sess); + final String[] paths = FileName.splitPath(name); + final AVMPath parentPath = buildStorePath(ctx, paths[0], sess); + final AVMPath filePath = buildStorePath(ctx, name, sess); + // DEBUG if (logger.isDebugEnabled()) - logger.debug("Delete file, path=" + name + ", storePath=" + storePath); + logger.debug("Delete file, path=" + name + ", filePath=" + filePath); // Check if the filesystem is the virtualization view if (ctx.isVirtualizationView()) { - if (storePath.isPseudoPath()) + if (parentPath.isPseudoPath()) throw new AccessDeniedException("Cannot delete file in store/version layer, " + name); - else if ( storePath.isReadOnlyAccess()) + else if ( parentPath.isReadOnlyAccess()) throw new AccessDeniedException("Cannot delete file " + name + ", read-only path"); } @@ -1171,7 +1177,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface public Void call() throws IOException { - AVMNodeDescriptor nodeDesc = m_avmService.lookup(storePath.getVersion(), storePath.getAVMPath()); + AVMNodeDescriptor nodeDesc = m_avmService.lookup(filePath.getVersion(), filePath.getAVMPath()); if (nodeDesc != null) { // Check that we are deleting a file @@ -1180,7 +1186,7 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface { // Delete the file - m_avmService.removeNode(storePath.getAVMPath()); + m_avmService.removeNode(filePath.getAVMPath()); } else throw new IOException("Delete file path is not a file, " + name); @@ -1697,7 +1703,9 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface throw new AccessDeniedException("Cannot rename folder in store/version layer, " + oldName); else if ( newAVMPath.isReadOnlyPseudoPath()) throw new AccessDeniedException("Cannot rename folder to store/version layer, " + newName); - else if ( newAVMPath.isReadOnlyAccess()) + else if ( oldAVMPath.isReadOnlyAccess() ) + throw new AccessDeniedException("Cannot rename read-only folder, " + oldName); + else if ( newAVMPath.isReadOnlyAccess() ) throw new AccessDeniedException("Cannot rename folder to read-only folder, " + newName); } @@ -2892,15 +2900,13 @@ public class AVMDiskDriver extends AlfrescoDiskDriver implements DiskInterface // Allow access to the root folder - if ( avmPath.isLevel() == AVMPath.LevelId.Root) { + if ( avmPath.isLevel() == AVMPath.LevelId.Root || avmPath.isLevel() == AVMPath.LevelId.HeadData || avmPath.isLevel() == AVMPath.LevelId.StoreRootPath ) { - // Allow read only access to the root - - avmPath.setReadOnlyAccess( true); + // Allow read only access to the root, www and avm_webapps folders + avmPath.setReadOnlyAccess(true); return; } - // Get root file state, get the store pseudo folder details FileState rootState = avmCtx.getStateCache().findFileState( FileName.DOS_SEPERATOR_STR); diff --git a/source/java/org/alfresco/filesys/avm/AVMPath.java b/source/java/org/alfresco/filesys/avm/AVMPath.java index 629370293b..62c26e56d1 100644 --- a/source/java/org/alfresco/filesys/avm/AVMPath.java +++ b/source/java/org/alfresco/filesys/avm/AVMPath.java @@ -59,7 +59,7 @@ public class AVMPath { // Level identifiers - public enum LevelId { Invalid, Root, StoreRoot, Head, HeadData, HeadMetaData, VersionRoot, Version, VersionData, VersionMetaData, StorePath }; + public enum LevelId { Invalid, Root, StoreRoot, Head, HeadData, HeadMetaData, VersionRoot, Version, VersionData, VersionMetaData, StoreRootPath, StorePath }; // Level identifier for this path @@ -138,9 +138,9 @@ public class AVMPath { * @return boolean */ public final boolean isReadOnlyAccess() { - return m_readOnly; + return m_readOnly; } - + /** * Return the store name * @@ -230,7 +230,7 @@ public class AVMPath { */ public final boolean isPseudoPath() { - return m_levelId == LevelId.Invalid || m_levelId == LevelId.StorePath ? false : true; + return m_levelId == LevelId.Invalid || m_levelId == LevelId.StorePath || m_levelId == LevelId.StoreRootPath ? false : true; } /** @@ -420,22 +420,32 @@ public class AVMPath { } // If there are remaining paths then build a relative path - if ( paths.length > pathIdx) { - StringBuilder pathStr = new StringBuilder(); - - for ( int i = pathIdx; i < paths.length; i++) - { - pathStr.append( FileName.DOS_SEPERATOR); - pathStr.append( paths[i]); - } - - m_path = pathStr.toString(); + StringBuilder pathStr = new StringBuilder(); + + for ( int i = pathIdx; i < paths.length; i++) + { + pathStr.append( FileName.DOS_SEPERATOR); + pathStr.append( paths[i]); + } + + m_path = pathStr.toString(); - // Set the level to indicate a store relative path - - m_levelId = LevelId.StorePath; + // ALF-1719: make "www" and "avm_webapps" read only by setting their level to + // StoreRootPath (which is checked in AVMDiskDriver.checkPathAccess). + String lastPath = paths[paths.length-1].toLowerCase(); + if(lastPath.equals("www") || lastPath.equals("avm_webapps")) + { + // Set the level to indicate a store root path i.e. "www", + // "avm_webapps" + m_levelId = LevelId.StoreRootPath; + } + else + { + // Set the level to indicate a store relative path + m_levelId = LevelId.StorePath; + } } // Build the AVM path, in :/ format @@ -508,8 +518,19 @@ public class AVMPath { m_avmPath = avmPath.toString(); // Indicate that the path is to a store relative path - - m_levelId = LevelId.StorePath; + + String lowerPath = path.toLowerCase(); + String[] paths = FileName.splitAllPaths(lowerPath); + if(paths[paths.length - 1].equals("www") || paths[paths.length - 1].equals("avm_webapps")) + { + // Set the level to indicate a store root path i.e. "www", + // "avm_webapps" + m_levelId = LevelId.StoreRootPath; + } + else + { + m_levelId = LevelId.StorePath; + } } /** @@ -523,7 +544,7 @@ public class AVMPath { int fid = -1; - if ( isLevel() == LevelId.StorePath) + if ( isLevel() == LevelId.StorePath || isLevel() == LevelId.StoreRootPath) { // Use the share relative path to generate the file id @@ -682,6 +703,7 @@ public class AVMPath { str.append("\\"); str.append( MetaDataFolder); break; + case StoreRootPath: case StorePath: str.append("["); str.append(getStoreName());