Improve JCR authorizations
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 18 Feb 2012 18:41:47 +0000 (18:41 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 18 Feb 2012 18:41:47 +0000 (18:41 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@5098 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/jackrabbit/JackrabbitAuthorizations.java
server/runtime/org.argeo.server.jackrabbit/src/main/resources/org/argeo/jackrabbit/repository-memory.xml
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/JcrUtils.java
server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/JcrAuthorizations.java [new file with mode: 0644]
server/runtime/org.argeo.server.jcr/src/test/java/org/argeo/jcr/AbstractInternalJackrabbitTestCase.java [new file with mode: 0644]
server/runtime/org.argeo.server.jcr/src/test/java/org/argeo/jcr/MapperTest.java
server/runtime/org.argeo.server.jcr/src/test/java/org/argeo/jcr/tabular/JcrTabularTest.java
server/runtime/org.argeo.server.jcr/src/test/java/org/argeo/server/jcr/JcrResourceAdapterTest.java
server/runtime/org.argeo.server.jcr/src/test/resources/org/argeo/server/jcr/repository-memory.xml [new file with mode: 0644]

index 3a731df58a74b9c47c5fc5c36585ebb3567d70a6..2347e8c7b37d644f479e85c31411473a9300d993 100644 (file)
 package org.argeo.jackrabbit;
 
+import java.security.Principal;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
 
-import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
-import javax.jcr.security.AccessControlList;
-import javax.jcr.security.AccessControlPolicy;
-import javax.jcr.security.AccessControlPolicyIterator;
-import javax.jcr.security.Privilege;
+import javax.jcr.Session;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.api.JackrabbitSession;
-import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
 import org.apache.jackrabbit.api.security.user.Authorizable;
-import org.apache.jackrabbit.api.security.user.Group;
 import org.apache.jackrabbit.api.security.user.UserManager;
 import org.argeo.ArgeoException;
-import org.argeo.jcr.JcrUtils;
+import org.argeo.jcr.security.JcrAuthorizations;
 
 /** Apply authorizations to a Jackrabbit repository. */
-public class JackrabbitAuthorizations {
+public class JackrabbitAuthorizations extends JcrAuthorizations {
        private final static Log log = LogFactory
                        .getLog(JackrabbitAuthorizations.class);
 
-       private Repository repository;
-       private Executor systemExecutor;
-
-       /**
-        * key := privilege1,privilege2/path/to/node<br/>
-        * value := group1,group2
-        */
-       private Map<String, String> groupPrivileges = new HashMap<String, String>();
-
-       public void init() {
-               Runnable action = new Runnable() {
-                       public void run() {
-                               JackrabbitSession session = null;
-                               try {
-                                       session = (JackrabbitSession) repository.login();
-                                       initAuthorizations(session);
-                               } catch (Exception e) {
-                                       JcrUtils.discardQuietly(session);
-                               } finally {
-                                       JcrUtils.logoutQuietly(session);
+       private List<String> groupPrefixes = new ArrayList<String>();
+
+       @Override
+       protected Principal getOrCreatePrincipal(Session session,
+                       String principalName) throws RepositoryException {
+               UserManager um = ((JackrabbitSession) session).getUserManager();
+               Authorizable authorizable = um.getAuthorizable(principalName);
+               if (authorizable == null) {
+                       groupPrefixes: for (String groupPrefix : groupPrefixes) {
+                               if (principalName.startsWith(groupPrefix)) {
+                                       authorizable = um.createGroup(principalName);
+                                       log.info("Created group " + principalName);
+                                       break groupPrefixes;
                                }
                        }
-               };
-
-               if (systemExecutor != null)
-                       systemExecutor.execute(action);
-               else
-                       action.run();
-       }
-
-       protected void initAuthorizations(JackrabbitSession session)
-                       throws RepositoryException {
-               JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session
-                               .getAccessControlManager();
-               UserManager um = session.getUserManager();
-
-               for (String privileges : groupPrivileges.keySet()) {
-                       String path = null;
-                       int slashIndex = privileges.indexOf('/');
-                       if (slashIndex == 0) {
-                               throw new ArgeoException("Privilege " + privileges
-                                               + " badly formatted it starts with /");
-                       } else if (slashIndex > 0) {
-                               path = privileges.substring(slashIndex);
-                               privileges = privileges.substring(0, slashIndex);
-                       }
-
-                       if (path == null)
-                               path = "/";
-
-                       List<Privilege> privs = new ArrayList<Privilege>();
-                       for (String priv : privileges.split(",")) {
-                               privs.add(acm.privilegeFromName(priv));
-                       }
-
-                       String groupNames = groupPrivileges.get(privileges);
-                       for (String groupName : groupNames.split(",")) {
-                               Group group = (Group) um.getAuthorizable(groupName);
-                               if (group == null)
-                                       group = um.createGroup(groupName);
-                               addPrivileges(session, group, path, privs);
-                       }
-               }
-               session.save();
-       }
-
-       public static void addPrivileges(JackrabbitSession session,
-                       Authorizable authorizable, String path, List<Privilege> privs)
-                       throws RepositoryException {
-               JackrabbitAccessControlManager acm = (JackrabbitAccessControlManager) session
-                               .getAccessControlManager();
-               AccessControlPolicy policy = null;
-               AccessControlPolicyIterator policyIterator = acm
-                               .getApplicablePolicies(path);
-               if (policyIterator.hasNext()) {
-                       policy = policyIterator.nextAccessControlPolicy();
-               } else {
-                       AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
-                       policy = existingPolicies[0];
-               }
-               if (policy instanceof AccessControlList) {
-                       ((AccessControlList) policy).addAccessControlEntry(
-                                       authorizable.getPrincipal(),
-                                       privs.toArray(new Privilege[privs.size()]));
-                       acm.setPolicy(path, policy);
+                       if (authorizable == null)
+                               throw new ArgeoException("Authorizable " + principalName
+                                               + " not found");
                }
-               if (log.isDebugEnabled())
-                       log.debug("Added privileges " + privs + " to " + authorizable
-                                       + " on " + path);
+               return authorizable.getPrincipal();
        }
 
-       public void setGroupPrivileges(Map<String, String> groupPrivileges) {
-               this.groupPrivileges = groupPrivileges;
+       public void setGroupPrefixes(List<String> groupsToCreate) {
+               this.groupPrefixes = groupsToCreate;
        }
-
-       public void setRepository(Repository repository) {
-               this.repository = repository;
-       }
-
-       public void setSystemExecutor(Executor systemExecutor) {
-               this.systemExecutor = systemExecutor;
-       }
-
 }
index 9f49e551ba34092919cd0fe71b9abef222ba5ef0..70cf190117c3ffdeefba8bec1ade9611f8a0895c 100644 (file)
@@ -7,7 +7,7 @@
 
        <!-- Workspace templates -->
        <Workspaces rootPath="${rep.home}/workspaces"
-               defaultWorkspace="${argeo.node.repo.defaultWorkspace}" configRootPath="/workspaces" />
+               defaultWorkspace="main" configRootPath="/workspaces" />
        <Workspace name="${wsp.name}">
                <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
                <PersistenceManager
index c847d5edd650b3b40fd757c00c8d12a0d86a1cb0..3aa6493786976dad6923ced7b7f0a9a64a0666ab 100644 (file)
@@ -21,6 +21,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.security.Principal;
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.util.ArrayList;
@@ -51,6 +52,12 @@ import javax.jcr.nodetype.NodeType;
 import javax.jcr.observation.EventListener;
 import javax.jcr.query.Query;
 import javax.jcr.query.QueryResult;
+import javax.jcr.security.AccessControlEntry;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
 import javax.jcr.version.VersionManager;
 
 import org.apache.commons.io.IOUtils;
@@ -504,6 +511,55 @@ public class JcrUtils implements ArgeoJcrConstants {
 
        }
 
+       /** Logs the effective access control policies */
+       public static void logEffectiveAccessPolicies(Node node) {
+               try {
+                       logEffectiveAccessPolicies(node.getSession(), node.getPath());
+               } catch (RepositoryException e) {
+                       log.error("Cannot log effective access policies of " + node, e);
+               }
+       }
+
+       /** Logs the effective access control policies */
+       public static void logEffectiveAccessPolicies(Session session, String path) {
+               if (!log.isDebugEnabled())
+                       return;
+
+               try {
+                       AccessControlPolicy[] effectivePolicies = session
+                                       .getAccessControlManager().getEffectivePolicies(path);
+                       if (effectivePolicies.length > 0) {
+                               for (AccessControlPolicy policy : effectivePolicies) {
+                                       if (policy instanceof AccessControlList) {
+                                               AccessControlList acl = (AccessControlList) policy;
+                                               log.debug("Access control list for " + path + "\n"
+                                                               + accessControlListSummary(acl));
+                                       }
+                               }
+                       } else {
+                               log.debug("No effective access control policy for " + path);
+                       }
+               } catch (RepositoryException e) {
+                       log.error("Cannot log effective access policies of " + path, e);
+               }
+       }
+
+       /** Returns a human-readable summary of this access control list. */
+       public static String accessControlListSummary(AccessControlList acl) {
+               StringBuffer buf = new StringBuffer("");
+               try {
+                       for (AccessControlEntry ace : acl.getAccessControlEntries()) {
+                               buf.append('\t').append(ace.getPrincipal().getName())
+                                               .append('\n');
+                               for (Privilege priv : ace.getPrivileges())
+                                       buf.append("\t\t").append(priv.getName()).append('\n');
+                       }
+                       return buf.toString();
+               } catch (RepositoryException e) {
+                       throw new ArgeoException("Cannot write summary of " + acl, e);
+               }
+       }
+
        /**
         * Copies recursively the content of a node to another one. Do NOT copy the
         * property values of {@link NodeType#MIX_CREATED} and
@@ -1307,4 +1363,48 @@ public class JcrUtils implements ArgeoJcrConstants {
                                        re);
                }
        }
+
+       /*
+        * SECURITY
+        */
+       /**
+        * Add privileges on a path to a {@link Principal}. The path must already
+        * exist.
+        */
+       public static void addPrivileges(Session session, String path,
+                       Principal principal, List<Privilege> privs)
+                       throws RepositoryException {
+               AccessControlManager acm = session.getAccessControlManager();
+               // search for an access control list
+               AccessControlList acl = null;
+               AccessControlPolicyIterator policyIterator = acm
+                               .getApplicablePolicies(path);
+               if (policyIterator.hasNext()) {
+                       while (policyIterator.hasNext()) {
+                               AccessControlPolicy acp = policyIterator
+                                               .nextAccessControlPolicy();
+                               if (acp instanceof AccessControlList)
+                                       acl = ((AccessControlList) acp);
+                       }
+               } else {
+                       AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
+                       for (AccessControlPolicy acp : existingPolicies) {
+                               if (acp instanceof AccessControlList)
+                                       acl = ((AccessControlList) acp);
+                       }
+               }
+
+               if (acl != null) {
+                       acl.addAccessControlEntry(principal,
+                                       privs.toArray(new Privilege[privs.size()]));
+                       acm.setPolicy(path, acl);
+                       if (log.isDebugEnabled())
+                               log.debug("Added privileges " + privs + " to " + principal
+                                               + " on " + path);
+               } else {
+                       throw new ArgeoException("Don't know how to apply  privileges "
+                                       + privs + " to " + principal + " on " + path);
+               }
+       }
+
 }
diff --git a/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/JcrAuthorizations.java b/server/runtime/org.argeo.server.jcr/src/main/java/org/argeo/jcr/security/JcrAuthorizations.java
new file mode 100644 (file)
index 0000000..f674162
--- /dev/null
@@ -0,0 +1,145 @@
+package org.argeo.jcr.security;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.security.AccessControlList;
+import javax.jcr.security.AccessControlManager;
+import javax.jcr.security.AccessControlPolicy;
+import javax.jcr.security.AccessControlPolicyIterator;
+import javax.jcr.security.Privilege;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.util.security.SimplePrincipal;
+
+/** Apply authorizations to a JCR repository. */
+public class JcrAuthorizations implements Runnable {
+       private final static Log log = LogFactory.getLog(JcrAuthorizations.class);
+
+       private Repository repository;
+
+       /**
+        * key := privilege1,privilege2/path/to/node<br/>
+        * value := group1,group2,user1
+        */
+       private Map<String, String> principalPrivileges = new HashMap<String, String>();
+
+       public void run() {
+               Session session = null;
+               try {
+                       session = repository.login();
+                       initAuthorizations(session);
+               } catch (Exception e) {
+                       JcrUtils.discardQuietly(session);
+               } finally {
+                       JcrUtils.logoutQuietly(session);
+               }
+       }
+
+       /** @deprecated call {@link #run()} instead. */
+       @Deprecated
+       public void init() {
+               run();
+       }
+
+       protected void initAuthorizations(Session session)
+                       throws RepositoryException {
+               AccessControlManager acm = session.getAccessControlManager();
+
+               for (String privileges : principalPrivileges.keySet()) {
+                       String path = null;
+                       int slashIndex = privileges.indexOf('/');
+                       if (slashIndex == 0) {
+                               throw new ArgeoException("Privilege " + privileges
+                                               + " badly formatted it starts with /");
+                       } else if (slashIndex > 0) {
+                               path = privileges.substring(slashIndex);
+                               privileges = privileges.substring(0, slashIndex);
+                       }
+
+                       if (path == null)
+                               path = "/";
+
+                       List<Privilege> privs = new ArrayList<Privilege>();
+                       for (String priv : privileges.split(",")) {
+                               privs.add(acm.privilegeFromName(priv));
+                       }
+
+                       String principalNames = principalPrivileges.get(privileges);
+                       for (String principalName : principalNames.split(",")) {
+                               Principal principal = getOrCreatePrincipal(session,
+                                               principalName);
+                               addPrivileges(session, principal, path, privs);
+                       }
+               }
+               session.save();
+       }
+
+       /**
+        * Returns a {@link SimplePrincipal}, does not check whether it exists since
+        * such capabilities is not provided by the standard JCR API. Can be
+        * overridden to provide smarter handling
+        */
+       protected Principal getOrCreatePrincipal(Session session,
+                       String principalName) throws RepositoryException {
+               return new SimplePrincipal(principalName);
+       }
+
+       public static void addPrivileges(Session session, Principal principal,
+                       String path, List<Privilege> privs) throws RepositoryException {
+               AccessControlManager acm = session.getAccessControlManager();
+               // search for an access control list
+               AccessControlList acl = null;
+               AccessControlPolicyIterator policyIterator = acm
+                               .getApplicablePolicies(path);
+               if (policyIterator.hasNext()) {
+                       while (policyIterator.hasNext()) {
+                               AccessControlPolicy acp = policyIterator
+                                               .nextAccessControlPolicy();
+                               if (acp instanceof AccessControlList)
+                                       acl = ((AccessControlList) acp);
+                       }
+               } else {
+                       AccessControlPolicy[] existingPolicies = acm.getPolicies(path);
+                       for (AccessControlPolicy acp : existingPolicies) {
+                               if (acp instanceof AccessControlList)
+                                       acl = ((AccessControlList) acp);
+                       }
+               }
+
+               if (acl != null) {
+                       acl.addAccessControlEntry(principal,
+                                       privs.toArray(new Privilege[privs.size()]));
+                       acm.setPolicy(path, acl);
+                       if (log.isDebugEnabled())
+                               log.debug("Added privileges " + privs + " to " + principal
+                                               + " on " + path);
+               } else {
+                       throw new ArgeoException("Don't know how to apply  privileges "
+                                       + privs + " to " + principal + " on " + path);
+               }
+       }
+
+       @Deprecated
+       public void setGroupPrivileges(Map<String, String> groupPrivileges) {
+               this.principalPrivileges = groupPrivileges;
+       }
+
+       public void setPrincipalPrivileges(Map<String, String> principalPrivileges) {
+               this.principalPrivileges = principalPrivileges;
+       }
+
+       public void setRepository(Repository repository) {
+               this.repository = repository;
+       }
+
+}
diff --git a/server/runtime/org.argeo.server.jcr/src/test/java/org/argeo/jcr/AbstractInternalJackrabbitTestCase.java b/server/runtime/org.argeo.server.jcr/src/test/java/org/argeo/jcr/AbstractInternalJackrabbitTestCase.java
new file mode 100644 (file)
index 0000000..078763f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.jcr;
+
+import java.io.File;
+
+import javax.jcr.Repository;
+
+import org.apache.jackrabbit.core.TransientRepository;
+import org.argeo.jcr.unit.AbstractJcrTestCase;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+
+/** Factorizes configuration of an in memory transient repository */
+public abstract class AbstractInternalJackrabbitTestCase extends
+               AbstractJcrTestCase {
+       protected File getRepositoryFile() throws Exception {
+               Resource res = new ClassPathResource(
+                               "org/argeo/server/jcr/repository-memory.xml");
+               return res.getFile();
+       }
+
+       protected Repository createRepository() throws Exception {
+               Repository repository = new TransientRepository(getRepositoryFile(),
+                               getHomeDir());
+               return repository;
+       }
+
+}
index 8f276991d18905cc61070cabbbd135d90f4c7ab6..03aab05fdb46871b0a717e0e6266b5ba305ca877 100644 (file)
 
 package org.argeo.jcr;
 
-import java.io.File;
-
 import javax.jcr.Node;
-import javax.jcr.Repository;
 
-import org.apache.jackrabbit.core.TransientRepository;
 import org.argeo.jcr.spring.BeanNodeMapper;
-import org.argeo.jcr.unit.AbstractJcrTestCase;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
 
-public class MapperTest extends AbstractJcrTestCase {
+public class MapperTest extends AbstractInternalJackrabbitTestCase {
        public void testSimpleObject() throws Exception {
                SimpleObject mySo = new SimpleObject();
                mySo.setInteger(100);
@@ -49,17 +42,4 @@ public class MapperTest extends AbstractJcrTestCase {
                session().save();
                JcrUtils.debug(node);
        }
-
-       protected File getRepositoryFile() throws Exception {
-               Resource res = new ClassPathResource(
-                               "org/argeo/server/jcr/repository-h2.xml");
-               return res.getFile();
-       }
-
-       protected Repository createRepository() throws Exception{
-               Repository repository = new TransientRepository(getRepositoryFile(), getHomeDir());
-               return repository;
-       }
-
-       
 }
index 7bb8e90bc5e83c5787df9a37b42075604083b182..672c8742076750f48b5f8df18d2a476f120fd921 100644 (file)
 
 package org.argeo.jcr.tabular;
 
-import java.io.File;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.jcr.Node;
 import javax.jcr.PropertyType;
-import javax.jcr.Repository;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.jackrabbit.commons.cnd.CndImporter;
-import org.apache.jackrabbit.core.TransientRepository;
+import org.argeo.jcr.AbstractInternalJackrabbitTestCase;
 import org.argeo.jcr.ArgeoNames;
 import org.argeo.jcr.ArgeoTypes;
-import org.argeo.jcr.unit.AbstractJcrTestCase;
 import org.argeo.util.tabular.TabularColumn;
 import org.argeo.util.tabular.TabularRow;
 import org.argeo.util.tabular.TabularRowIterator;
 import org.argeo.util.tabular.TabularWriter;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
 
-public class JcrTabularTest extends AbstractJcrTestCase {
+public class JcrTabularTest extends AbstractInternalJackrabbitTestCase {
        private final static Log log = LogFactory.getLog(JcrTabularTest.class);
 
        public void testWriteReadCsv() throws Exception {
@@ -88,23 +83,4 @@ public class JcrTabularTest extends AbstractJcrTestCase {
                        log.debug("Read tabular content " + rowCount + " rows, "
                                        + columnCount + " columns");
        }
-
-       protected File getRepositoryFile() throws Exception {
-               Resource res = new ClassPathResource(
-                               "org/argeo/server/jcr/repository-h2.xml");
-               return res.getFile();
-       }
-
-       protected Repository createRepository() throws Exception {
-               // JackrabbitContainer repo = new JackrabbitContainer();
-               // repo.setHomeDirectory(getHomeDir());
-               // repo.setConfiguration(new FileSystemResource(
-               // getRepositoryFile()));
-               // repo.setInMemory(true);
-               // repo.set
-               Repository repository = new TransientRepository(getRepositoryFile(),
-                               getHomeDir());
-               return repository;
-       }
-
 }
index 32bfa9fc277ac9f555d557c263ecf49ee8ad1977..400811341e9d8e8ee83d1fb7950fcbcc13a4f022 100644 (file)
 
 package org.argeo.server.jcr;
 
-import java.io.File;
 import java.io.InputStream;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.List;
 
-import javax.jcr.Repository;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.core.TransientRepository;
+import org.argeo.jcr.AbstractInternalJackrabbitTestCase;
 import org.argeo.jcr.JcrResourceAdapter;
-import org.argeo.jcr.unit.AbstractJcrTestCase;
 import org.springframework.core.io.ClassPathResource;
 import org.springframework.core.io.Resource;
 
-public class JcrResourceAdapterTest extends AbstractJcrTestCase {
+public class JcrResourceAdapterTest extends AbstractInternalJackrabbitTestCase {
        private static SimpleDateFormat sdf = new SimpleDateFormat(
                        "yyyyMMdd:hhmmss.SSS");
 
@@ -103,17 +99,4 @@ public class JcrResourceAdapterTest extends AbstractJcrTestCase {
                log.debug("TEAR DOWN");
                super.tearDown();
        }
-
-       protected File getRepositoryFile() throws Exception {
-               Resource res = new ClassPathResource(
-                               "org/argeo/server/jcr/repository-h2.xml");
-               return res.getFile();
-       }
-
-       protected Repository createRepository() throws Exception {
-               Repository repository = new TransientRepository(getRepositoryFile(),
-                               getHomeDir());
-               return repository;
-       }
-
 }
diff --git a/server/runtime/org.argeo.server.jcr/src/test/resources/org/argeo/server/jcr/repository-memory.xml b/server/runtime/org.argeo.server.jcr/src/test/resources/org/argeo/server/jcr/repository-memory.xml
new file mode 100644 (file)
index 0000000..d1790af
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 1.6//EN"
+                            "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+<Repository>
+       <!-- File system and datastore -->
+       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+
+       <!-- Workspace templates -->
+       <Workspaces rootPath="${rep.home}/workspaces"
+               defaultWorkspace="main" configRootPath="/workspaces" />
+       <Workspace name="${wsp.name}">
+               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+               <PersistenceManager
+                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
+                       <param name="blobFSBlockSize" value="1" />
+               </PersistenceManager>
+               <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+                       <param name="path" value="${rep.home}/repository/index" />
+                       <param name="directoryManagerClass"
+                               value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+                       <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+               </SearchIndex>
+       </Workspace>
+
+       <!-- Versioning -->
+       <Versioning rootPath="${rep.home}/version">
+               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+               <PersistenceManager
+                       class="org.apache.jackrabbit.core.persistence.bundle.BundleFsPersistenceManager">
+                       <param name="blobFSBlockSize" value="1" />
+               </PersistenceManager>
+       </Versioning>
+
+       <!-- Indexing -->
+       <SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+               <param name="path" value="${rep.home}/repository/index" />
+               <param name="directoryManagerClass"
+                       value="org.apache.jackrabbit.core.query.lucene.directory.RAMDirectoryManager" />
+               <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem" />
+       </SearchIndex>
+
+       <!-- Security -->
+       <Security appName="Jackrabbit">
+               <SecurityManager
+                       class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager"
+                       workspaceName="security" />
+               <AccessManager
+                       class="org.apache.jackrabbit.core.security.simple.SimpleAccessManager" />
+               <LoginModule
+                       class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
+                       <param name="anonymousId" value="anonymous" />
+                       <param name="adminId" value="admin" />
+               </LoginModule>
+       </Security>
+</Repository>
\ No newline at end of file