Hello, 

We are working on an opensource Document management system named Dissco 
(http://www.meteo.be/DISSCO/)

Dissco is heavily based on Slide, and working on it, I found a bug in the copy 
Macro.

This bug prevent from copying a "read-only" file.

macro copy is done by the 3 following step.
1) create the new node
2) copying permissions
3) copying content and properties

... and it should be ...
1) create the new node
2) copying content and properties
3) copying permissions

... because, if you copy the permission 
[node, subject=all, action=/actions/write-content, negative=true] before 
copying content, it throw an AccessDeniedException.

You'll find a patch as attachement.
You can also find a testcase ilustrating the bug.


-- 
Honor� David

----------------------------
"They don't make bugs like Bunny anymore." --Olav Mjelde

Index: MacroImpl.java
===================================================================
RCS file: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/macro/MacroImpl.java,v
retrieving revision 1.50
diff -u -r1.50 MacroImpl.java
--- MacroImpl.java	8 Nov 2004 09:22:56 -0000	1.50
+++ MacroImpl.java	1 Dec 2004 11:05:48 -0000
@@ -813,31 +813,6 @@
                 }
             }
             
-            // Trying to recreate permissions
-            try {
-                
-                Enumeration sourcePermissions = securityHelper
-                    .enumeratePermissions(token, sourceNode);
-                
-                while (sourcePermissions.hasMoreElements()) {
-                    NodePermission permission =
-                        (NodePermission) sourcePermissions.nextElement();
-                    NodePermission newPermission =
-                        new NodePermission(destinationUri,
-                                           permission.getSubjectUri(),
-                                           permission.getActionUri(),
-                                           permission.isInheritable(),
-                                           permission.isNegative());
-                    securityHelper.grantPermission(token, newPermission);
-                }
-                
-            } catch (AccessDeniedException ex) {
-                // Means that we don't have modifyPermissions rights
-                // (root access) on the target.
-                // The copy should definitely succeed anyway,
-                // so we silently catch the exception.
-            }
-            
             // Now copying revision descriptors and content
             NodeRevisionDescriptors sourceNrds =
                 contentHelper.retrieve(token, sourceNode.getUri());
@@ -883,6 +858,31 @@
                 }
             }
             
+            // Trying to recreate permissions
+            try {
+                
+                Enumeration sourcePermissions = securityHelper
+                    .enumeratePermissions(token, sourceNode);
+                
+                while (sourcePermissions.hasMoreElements()) {
+                    NodePermission permission =
+                        (NodePermission) sourcePermissions.nextElement();
+                    NodePermission newPermission =
+                        new NodePermission(destinationUri,
+                                           permission.getSubjectUri(),
+                                           permission.getActionUri(),
+                                           permission.isInheritable(),
+                                           permission.isNegative());
+                    securityHelper.grantPermission(token, newPermission);
+                }
+                
+            } catch (AccessDeniedException ex) {
+                // Means that we don't have modifyPermissions rights
+                // (root access) on the target.
+                // The copy should definitely succeed anyway,
+                // so we silently catch the exception.
+            }
+              
         } catch(SlideException ex) {
             // ex.printStackTrace(); //the exception is packed and
             // (hopefully) reported in the response
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;

import org.apache.commons.io.FileUtils;
import org.apache.slide.authenticate.CredentialsToken;
import org.apache.slide.authenticate.SecurityToken;
import org.apache.slide.common.Domain;
import org.apache.slide.common.NamespaceAccessToken;
import org.apache.slide.common.SlideToken;
import org.apache.slide.common.SlideTokenImpl;
import org.apache.slide.content.Content;
import org.apache.slide.content.NodeRevisionContent;
import org.apache.slide.content.NodeRevisionDescriptor;
import org.apache.slide.macro.Macro;
import org.apache.slide.security.NodePermission;
import org.apache.slide.security.Security;
import org.apache.slide.structure.ActionNode;
import org.apache.slide.structure.Structure;
import org.apache.slide.structure.SubjectNode;



import junit.framework.TestCase;
/*
 * Created on Dec 2, 2004
 * by davidh
 *
 */

/**
 * @author davidh
 *
 */
public class copyTest extends TestCase {

    static final String ENTITY_URI="/files/test";
    
    public void testcopy() throws Exception {
        
        FileUtils.deleteDirectory(new File("store"));
        FileUtils.deleteDirectory(new File("work"));
        FileUtils.deleteDirectory(new File("index"));
        
        ArrayList al;
        
        // Initialise Slide
        SlideToken st = new SlideTokenImpl(new CredentialsToken("root"));
        st.setForceStoreEnlistment(true);
        NamespaceAccessToken nat = Domain.accessNamespace(new SecurityToken(st),"slide");

        Macro macro = nat.getMacroHelper();
        Structure structure = nat.getStructureHelper();
        Content content = nat.getContentHelper();
        Security security = nat.getSecurityHelper();
        
        // Grant all permisions to all for /files
        nat.begin();
        al = Collections.list(security.enumeratePermissions(st, SubjectNode.getSubjectNode("/files")));
        al.add(0,new NodePermission( "/files", SubjectNode.ALL_URI, ActionNode.ALL_URI, true, false));
        security.setPermissions(st, "/files", Collections.enumeration(al));
        nat.commit();
        
        
        // Part one ... Create the node
        nat.begin();
        structure.create(st, new SubjectNode(ENTITY_URI), ENTITY_URI);
        content.create(st, ENTITY_URI, false);
        
        NodeRevisionDescriptor nrd = new NodeRevisionDescriptor(4);
        NodeRevisionContent nrc = new NodeRevisionContent();
        
        nrc.setContent("test".toCharArray());
        
        content.create(st, ENTITY_URI, nrd, nrc);
        nat.commit();
        
        // Part two ... Set Read-only content   (deny Modify)
        nat.begin();
        al = Collections.list(security.enumeratePermissions(st, SubjectNode.getSubjectNode(ENTITY_URI)));
        al.add(0, new NodePermission(ENTITY_URI, SubjectNode.ALL_URI, nat.getNamespaceConfig().getModifyRevisionContentAction().getUri(), false, true));
        security.setPermissions(st, ENTITY_URI, Collections.enumeration(al));
        nat.commit();
        
        // Part three ... try to copy ReadOnly Node
        nat.begin();
        macro.copy(st, ENTITY_URI, ENTITY_URI+"_copy");        
        nat.commit();

        // Set "/files" to readonly
        nat.begin();
        al = Collections.list(security.enumeratePermissions(st, SubjectNode.getSubjectNode("/files")));
        al.add(0,new NodePermission( SubjectNode.getSubjectNode("/files"), SubjectNode.ALL, ActionNode.ALL, true, true));
        security.setPermissions(st, "/files", Collections.enumeration(al));
        nat.commit();
        
        
        // Part three ... try to copy ReadOnly Node to readonly space (must fail)
        try {
	        nat.begin();
	        macro.copy(st, ENTITY_URI, ENTITY_URI+"_copy2");        
	        nat.commit();
	        fail();
        } catch (Exception e) {
        }
    }
    
    
}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to