You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2012/01/17 19:02:48 UTC

svn commit: r1232513 - in /jackrabbit/branches/2.4: ./ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorizat...

Author: jukka
Date: Tue Jan 17 18:02:48 2012
New Revision: 1232513

URL: http://svn.apache.org/viewvc?rev=1232513&view=rev
Log:
2.4: Merged revisions 1227171, 1228058, 1230681 and 1225179 (JCR-2859 and JCR-3195)

Modified:
    jackrabbit/branches/2.4/   (props changed)
    jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
    jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java
    jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractLockManagementTest.java
    jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockManagerTest.java
    jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockTest.java
    jackrabbit/branches/2.4/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/OpenScopedLockTest.java
    jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java
    jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
    jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java

Propchange: jackrabbit/branches/2.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jan 17 18:02:48 2012
@@ -1,3 +1,3 @@
 /jackrabbit/branches/JCR-2272:1173165-1176545
 /jackrabbit/sandbox/JCR-2415-lucene-3.0:1060860-1064038
-/jackrabbit/trunk:1221447,1221579,1221593,1221789,1221818,1225179,1225191,1225196,1225207,1225525,1225528,1226452,1226472,1226515,1226750,1226863,1227240,1227590,1227593,1227615,1232100
+/jackrabbit/trunk:1221447,1221579,1221593,1221789,1221818,1225179,1225191,1225196,1225207,1225525,1225528,1226452,1226472,1226515,1226750,1226863,1227171,1227240,1227590,1227593,1227615,1228058,1230681,1232100

Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockImpl.java Tue Jan 17 18:02:48 2012
@@ -22,6 +22,7 @@ import org.apache.jackrabbit.core.securi
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 import javax.jcr.lock.LockException;
 
 /**
@@ -78,7 +79,7 @@ class LockImpl implements javax.jcr.lock
      * {@inheritDoc}
      */
     public String getLockToken() {
-        if (!info.isSessionScoped() && info.isLockHolder(node.getSession())) {
+        if (!info.isSessionScoped() && (info.isLockHolder(node.getSession()) || isAdminUser(node.getSession()))) {
             return info.getLockToken();
         } else {
             return null;
@@ -151,4 +152,15 @@ class LockImpl implements javax.jcr.lock
         return info.isLockHolder(node.getSession());
     }
 
+    /**
+     * Check whether a session belongs to an administrative user.
+     */
+    private boolean isAdminUser(Session session) {
+        if (session instanceof SessionImpl) {
+            return ((SessionImpl) session).isAdmin();
+        } else {
+            // fallback. use hardcoded default admin ID
+            return "admin".equals(session.getUserID());
+        }
+    }
 }

Modified: jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java Tue Jan 17 18:02:48 2012
@@ -941,14 +941,21 @@ public class XATest extends AbstractJCRT
         n.save();
 
         superuser.removeLockToken(lockToken);
-        assertNull("session must get a null lock token", lock.getLockToken());
+
+        String nlt = lock.getLockToken();
+        assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                nlt == null || nlt.equals(lockToken));
+
         assertFalse("session must not hold lock token", containsLockToken(superuser, lockToken));
         
         // commit
         utx.commit();
 
+        nlt = lock.getLockToken();
+        assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                nlt == null || nlt.equals(lockToken));
+
         assertFalse("session must not hold lock token", containsLockToken(superuser, lockToken));
-        assertNull("session must get a null lock token", lock.getLockToken());
 
         // start new Transaction and try to unlock
         utx = new UserTransactionImpl(superuser);
@@ -1141,7 +1148,10 @@ public class XATest extends AbstractJCRT
         assertTrue("session must hold lock token", containsLockToken(superuser, lockToken));
 
         superuser.removeLockToken(lockToken);
-        assertNull("session must get a null lock token", lock.getLockToken());
+
+        String nlt = lock.getLockToken();
+        assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                nlt == null || nlt.equals(lockToken));
 
         // commit
         utx.commit();
@@ -1149,7 +1159,9 @@ public class XATest extends AbstractJCRT
         // refresh Lock Info
         lock = n.getLock();
 
-        assertNull("session must get a null lock token", lock.getLockToken());
+        nlt = lock.getLockToken();
+        assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                nlt == null || nlt.equals(lockToken));
 
         Session other = getHelper().getSuperuserSession();
         try {
@@ -1910,15 +1922,20 @@ public class XATest extends AbstractJCRT
         assertTrue("session must hold lock token", containsLockToken(superuser, lockToken));
 
         superuser.removeLockToken(lockToken);
-        assertNull("session must get a null lock token", lock.getLockToken());
-        
+
+        String nlt = lock.getLockToken();
+        assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                nlt == null || nlt.equals(lockToken));
+
         // commit
         utx.commit();
         
         // refresh Lock Info
         lock = n.getLock();
 
-        assertNull("session must get a null lock token", lock.getLockToken());
+        nlt = lock.getLockToken();
+        assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                nlt == null || nlt.equals(lockToken));
 
         Session other = getHelper().getSuperuserSession();
         // start new Transaction and try to add lock token unlock the node and then remove it

Modified: jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractLockManagementTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractLockManagementTest.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractLockManagementTest.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/security/authorization/AbstractLockManagementTest.java Tue Jan 17 18:02:48 2012
@@ -22,7 +22,9 @@ import org.apache.jackrabbit.test.NotExe
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.jcr.Session;
 import javax.jcr.lock.Lock;
+import javax.jcr.lock.LockManager;
 
 /** <code>AbstractVersionAccessTest</code>... */
 public abstract class AbstractLockManagementTest extends AbstractEvaluationTest {
@@ -129,4 +131,49 @@ public abstract class AbstractLockManage
         boolean isLocked = n.isLocked();
         assertFalse(isLocked);
     }
+
+    public void testLockBreaking() throws RepositoryException, NotExecutableException {
+        String locktoken = null;
+        LockManager sulm = superuser.getWorkspace().getLockManager();
+        String lockedpath = null;
+
+        try {
+            Node trn = getTestNode();
+            modifyPrivileges(trn.getPath(), Privilege.JCR_READ, true);
+            modifyPrivileges(trn.getPath(), PrivilegeRegistry.REP_WRITE, true);
+            modifyPrivileges(trn.getPath(), Privilege.JCR_LOCK_MANAGEMENT, true);
+
+            Session lockingSession = trn.getSession();
+
+            assertFalse("super user and test user should have different user ids: " + lockingSession.getUserID() + " vs " + superuser.getUserID(),
+                    lockingSession.getUserID().equals(superuser.getUserID()));
+
+            trn.addNode("locktest", "nt:unstructured");
+            trn.addMixin("mix:lockable");
+            lockingSession.save();
+
+            // let the "other" user lock the node
+            LockManager oulm = lockingSession.getWorkspace().getLockManager();
+            Lock l = oulm.lock(trn.getPath(), true, false, Long.MAX_VALUE, null);
+            lockedpath = trn.getPath();
+            locktoken = l.getLockToken();
+            lockingSession.logout();
+
+            // transfer the lock token to the super user and try the unlock
+
+            Node lockednode = superuser.getNode(lockedpath);
+            assertTrue(lockednode.isLocked());
+            Lock sl = sulm.getLock(lockedpath);
+            assertNotNull(sl.getLockToken());
+            sulm.addLockToken(sl.getLockToken());
+            sulm.unlock(lockedpath);
+            locktoken = null;
+        }
+        finally {
+            if (locktoken != null && lockedpath != null) {
+                sulm.addLockToken(locktoken);
+                sulm.unlock(lockedpath);
+            }
+        }
+    }
 }

Modified: jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockManagerTest.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockManagerTest.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockManagerTest.java Tue Jan 17 18:02:48 2012
@@ -239,7 +239,9 @@ public class LockManagerTest extends Abs
         try {
             lockMgr.removeLockToken(ltoken);
 
-            assertNull("Lock token must not be exposed any more.", l.getLockToken());
+            String nlt = l.getLockToken();
+            assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                    nlt == null || nlt.equals(ltoken));
         } finally {
             // make sure lock token is added even if test fail
             lockMgr.addLockToken(ltoken);

Modified: jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockTest.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockTest.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/lock/LockTest.java Tue Jan 17 18:02:48 2012
@@ -64,8 +64,10 @@ public class LockTest extends AbstractJC
 
             // remove lock token
             superuser.removeLockToken(lockToken);
-            // assert: session must get a null lock token
-            assertNull("session must get a null lock token", lock.getLockToken());
+
+            String nlt = lock.getLockToken();
+            assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                    nlt == null || nlt.equals(lockToken));
 
             // assert: session must still hold lock token
             assertFalse("session must not hold lock token",
@@ -427,8 +429,9 @@ public class LockTest extends AbstractJC
             otherSuperuser.removeLockToken(lockToken);
             superuser.addLockToken(lockToken);
 
-            // assert: user must get null token
-            assertNull("user must get null token", lock.getLockToken());
+            String nlt = lock.getLockToken();
+            assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                    nlt == null || nlt.equals(lockToken));
 
             // assert: user must get non-null token
             assertNotNull("user must get non-null token",

Modified: jackrabbit/branches/2.4/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/OpenScopedLockTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/OpenScopedLockTest.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/OpenScopedLockTest.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-jcr2spi/src/test/java/org/apache/jackrabbit/jcr2spi/lock/OpenScopedLockTest.java Tue Jan 17 18:02:48 2012
@@ -89,7 +89,10 @@ public class OpenScopedLockTest extends 
         String lockToken = lock.getLockToken();
         try {
             superuser.removeLockToken(lockToken);
-            assertNull("After token transfer lock-token must not be visible", lock.getLockToken());
+
+            String nlt = lock.getLockToken();
+            assertTrue("freshly obtained lock token must either be null or the same as the one returned earlier",
+                    nlt == null || nlt.equals(lockToken));
         } finally {
             // move lock token back in order to have lock removed properly
             superuser.addLockToken(lockToken);

Modified: jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/LockInfoImpl.java Tue Jan 17 18:02:48 2012
@@ -15,12 +15,14 @@
 */
 package org.apache.jackrabbit.spi2dav;
 
-import org.apache.jackrabbit.webdav.lock.ActiveLock;
-import org.apache.jackrabbit.webdav.DavConstants;
+import java.util.Set;
+
 import org.apache.jackrabbit.spi.LockInfo;
 import org.apache.jackrabbit.spi.NodeId;
-import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.webdav.DavConstants;
+import org.apache.jackrabbit.webdav.lock.ActiveLock;
 import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * <code>LockInfoImpl</code>...
@@ -31,10 +33,12 @@ public class LockInfoImpl implements Loc
 
     private final ActiveLock activeLock;
     private final NodeId nodeId;
+    private final Set<String> sessionLockTokens;
 
-    public LockInfoImpl(ActiveLock activeLock, NodeId nodeId) {
+    public LockInfoImpl(ActiveLock activeLock, NodeId nodeId, Set<String> sessionLockTokens) {
         this.activeLock = activeLock;
         this.nodeId = nodeId;
+        this.sessionLockTokens = sessionLockTokens;
     }
 
     ActiveLock getActiveLock() {
@@ -64,7 +68,12 @@ public class LockInfoImpl implements Loc
     }
 
     public boolean isLockOwner() {
-        return activeLock.getToken() != null;
+        String lt = activeLock.getToken();
+        if (lt == null) {
+            return false;
+        } else {
+            return sessionLockTokens.contains(lt);
+        }
     }
 
     public NodeId getNodeId() {

Modified: jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Tue Jan 17 18:02:48 2012
@@ -374,9 +374,10 @@ public class RepositoryServiceImpl imple
     protected static void initMethod(HttpMethod method, SessionInfo sessionInfo, boolean addIfHeader) throws RepositoryException {
         if (addIfHeader) {
             checkSessionInfo(sessionInfo);
-            String[] locktokens = ((SessionInfoImpl) sessionInfo).getAllLockTokens();
+            Set<String> allLockTokens = ((SessionInfoImpl) sessionInfo).getAllLockTokens();
             // TODO: ev. build tagged if header
-            if (locktokens != null && locktokens.length > 0) {
+            if (!allLockTokens.isEmpty()) {
+                String[] locktokens = allLockTokens.toArray(new String[allLockTokens.size()]);
                 IfHeader ifH = new IfHeader(locktokens);
                 method.setRequestHeader(ifH.getHeaderName(), ifH.getHeaderValue());
             }
@@ -1571,7 +1572,9 @@ public class RepositoryServiceImpl imple
         String uri = getItemUri(nodeId, sessionInfo);
         // since sessionInfo does not allow to retrieve token by NodeId,
         // pass all available lock tokens to the LOCK method (TODO: correct?)
-        LockMethod method = new LockMethod(uri, INFINITE_TIMEOUT, ((SessionInfoImpl) sessionInfo).getAllLockTokens());
+        Set<String> allLockTokens = ((SessionInfoImpl) sessionInfo).getAllLockTokens();
+        String[] locktokens = allLockTokens.toArray(new String[allLockTokens.size()]);
+        LockMethod method = new LockMethod(uri, INFINITE_TIMEOUT, locktokens);
         execute(method, sessionInfo);
     }
 
@@ -1592,6 +1595,10 @@ public class RepositoryServiceImpl imple
         String lockToken = lInfo.getActiveLock().getToken();
         boolean isSessionScoped = lInfo.isSessionScoped();
 
+        if (!((SessionInfoImpl) sessionInfo).getAllLockTokens().contains(lockToken)) {
+            throw new LockException("Lock " + lockToken + " not owned by this session");
+        }
+
         UnLockMethod method = new UnLockMethod(uri, lockToken);
         execute(method, sessionInfo);
 
@@ -1600,6 +1607,7 @@ public class RepositoryServiceImpl imple
 
     private LockInfo retrieveLockInfo(LockDiscovery lockDiscovery, SessionInfo sessionInfo,
                                       NodeId nodeId, NodeId parentId) throws RepositoryException {
+        checkSessionInfo(sessionInfo);
         List<ActiveLock> activeLocks = lockDiscovery.getValue();
         ActiveLock activeLock = null;
         for (ActiveLock l : activeLocks) {
@@ -1625,7 +1633,7 @@ public class RepositoryServiceImpl imple
         }
         // no deep lock or parentID == null or lock is not present on parent
         // -> nodeID is lockHolding Id.
-        return new LockInfoImpl(activeLock, nodeId);
+        return new LockInfoImpl(activeLock, nodeId, ((SessionInfoImpl)sessionInfo).getAllLockTokens());
     }
 
     /**

Modified: jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java?rev=1232513&r1=1232512&r2=1232513&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/SessionInfoImpl.java Tue Jan 17 18:02:48 2012
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.spi2dav;
 
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.Arrays;
@@ -98,10 +99,10 @@ public class SessionInfoImpl extends org
      * communication with the DAV server and are never exposed through the
      * JCR API for they belong to session-scoped locks.
      */
-    String[] getAllLockTokens() {
+    Set<String> getAllLockTokens() {
         Set<String> s = new HashSet<String>(Arrays.asList(getLockTokens()));
         s.addAll(sessionScopedTokens);
-        return s.toArray(new String[s.size()]);
+        return Collections.unmodifiableSet(s);
     }
 
     void addLockToken(String token, boolean sessionScoped) {