You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2012/10/23 11:40:16 UTC
svn commit: r1401220 - in /sling/trunk: ./ bundles/jcr/jackrabbit-base/
bundles/jcr/jackrabbit-base/src/ bundles/jcr/jackrabbit-base/src/main/
bundles/jcr/jackrabbit-base/src/main/java/
bundles/jcr/jackrabbit-base/src/main/java/org/ bundles/jcr/jackrab...
Author: cziegeler
Date: Tue Oct 23 09:40:15 2012
New Revision: 1401220
URL: http://svn.apache.org/viewvc?rev=1401220&view=rev
Log:
SLING-2624 : Improving Jackrabbit integration with OSGi Service Registry. Apply patch from Chetan Mehrotra
Added:
sling/trunk/bundles/jcr/jackrabbit-base/ (with props)
sling/trunk/bundles/jcr/jackrabbit-base/pom.xml (with props)
sling/trunk/bundles/jcr/jackrabbit-base/src/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/OsgiBeanFactory.java (with props)
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingLoginModule.java (with props)
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingPrincipalProviderRegistry.java (with props)
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/MultiplexingAuthorizableAction.java (with props)
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/PrincipalProviderTracker.java (with props)
sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/package-info.java (with props)
sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java (with props)
sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java (with props)
Modified:
sling/trunk/bundles/jcr/jackrabbit-server/pom.xml
sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/Activator.java
sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/SlingServerRepository.java
sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/TrustedCredentials.java
sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml
sling/trunk/pom.xml
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Oct 23 09:40:15 2012
@@ -0,0 +1,14 @@
+target
+sling
+bin
+logs
+jackrabbit-repository
+derby.log
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders
+maven-eclipse.xml
Added: sling/trunk/bundles/jcr/jackrabbit-base/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base/pom.xml?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-base/pom.xml (added)
+++ sling/trunk/bundles/jcr/jackrabbit-base/pom.xml Tue Oct 23 09:40:15 2012
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>13</version>
+ <relativePath>../../../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>org.apache.sling.jcr.jackrabbit.base</artifactId>
+ <packaging>bundle</packaging>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <name>Apache Sling JCR Jackrabbit Base</name>
+ <description>
+ The JCR base bundle provides Jackrabbit utility classes
+ </description>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-base</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-base</developerConnection>
+ <url>http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <configuration>
+ <!-- Skip the check for JDK 5 API -->
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ <version>2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-core</artifactId>
+ <version>2.5.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- OSGi Libraries -->
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>4.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>4.2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>biz.aQute</groupId>
+ <artifactId>bndlib</artifactId>
+ <version>1.50.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/pom.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/OsgiBeanFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/OsgiBeanFactory.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/OsgiBeanFactory.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/OsgiBeanFactory.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.jcr.jackrabbit.base.config;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.jackrabbit.core.config.BeanConfig;
+import org.apache.jackrabbit.core.config.BeanConfigVisitor;
+import org.apache.jackrabbit.core.config.BeanFactory;
+import org.apache.jackrabbit.core.config.ConfigurationException;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.apache.jackrabbit.core.config.SimpleBeanFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
+
+
+public class OsgiBeanFactory implements BeanFactory, ServiceTrackerCustomizer {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private final BeanFactory delegate = new SimpleBeanFactory();
+ private final BundleContext bundleContext;
+
+ /**
+ * Tracker to track all services which are possible Jackrabbit extensions
+ */
+ private final ServiceTracker tracker;
+
+ /**
+ * Set of all interface class instances for which actual instances need to
+ * be lookedup from OSGi Service Registry
+ */
+ private final Set<Class> dependencies = new HashSet<Class>();
+
+ /**
+ * Map of className to class instances
+ */
+ private final Map<String, Class> classNameMapping = new HashMap<String, Class>();
+
+ /**
+ * Map of the interface name -> instance where the instance provides an implementation
+ * of the given interface
+ */
+ private final Map<Class, Object> instanceMap = new ConcurrentHashMap<Class, Object>();
+
+ private ServiceRegistration beanFactoryReg;
+
+ public OsgiBeanFactory(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ Filter filter = null;
+ try {
+ filter = bundleContext.createFilter("(jackrabbit.extension=true)");
+ } catch (InvalidSyntaxException e) {
+ //Should not happen
+ throw new RuntimeException("Invalid filter", e);
+ }
+ this.tracker = new ServiceTracker(bundleContext, filter, this);
+ }
+
+ public void initialize(InputSource configSource) throws IOException, ConfigurationException {
+ determineDependencies(configSource);
+ createClassNameMappings();
+ tracker.open();
+ checkState();
+ }
+
+ public void close() {
+ if (beanFactoryReg != null) {
+ beanFactoryReg.unregister();
+ beanFactoryReg = null;
+ }
+ tracker.close();
+ dependencies.clear();
+ instanceMap.clear();
+ classNameMapping.clear();
+ }
+
+ //-----------------------------------------------< BeanFactory >
+
+ public Object newInstance(Class<?> clazz, BeanConfig config) throws ConfigurationException {
+ Class targetClass = getClassFromConfig(config);
+ if (targetClass.isInterface()) {
+ Object o = instanceMap.get(targetClass);
+ if (o == null) {
+ throw new ConfigurationException("No instance registered for type " + targetClass.getName());
+ }
+ return o;
+ }
+ return delegate.newInstance(clazz, config);
+ }
+
+ //-----------------------------------------------< ServiceTrackerCustomizer >
+
+ public Object addingService(ServiceReference reference) {
+ Object instance = bundleContext.getService(reference);
+ Class[] depsProvided = determineProvidedDependencies(reference);
+ registerInstance(depsProvided, instance);
+ checkState();
+ return depsProvided;
+ }
+
+ public void modifiedService(ServiceReference serviceReference, Object o) {
+
+ }
+
+ public void removedService(ServiceReference reference, Object o) {
+ deregisterInstance((Class[]) o);
+ checkState();
+ bundleContext.ungetService(reference);
+ }
+
+ //------------------------- Callback methods
+
+ /**
+ * Callback method invoked when all services required by Jackrabbit are available. Implementing class
+ * can use this to manage repository lifecycle. Default implementation registers the BeanFactory
+ * instance which would be used by the Repository creator to create the repository
+ */
+ protected void dependenciesSatisfied() {
+ //TODO Review the thread safety aspect
+ ServiceRegistration reg = beanFactoryReg;
+ if (reg == null) {
+ beanFactoryReg = bundleContext.registerService(BeanFactory.class.getName(), this, new Properties());
+ log.info("All dependencies are satisfied. Registering the BeanFactory instance");
+ }
+ }
+
+ /**
+ * Callback method invoked when any of the service required by Jackrabbit goes away. Implementing class
+ * can use this to manage repository lifecycle. Default implementation de-registers the BeanFactory
+ * instance. And repository creator service which then depends on BeanFactory reference would then be notified and
+ * can react accordingly
+ */
+ protected void dependenciesUnSatisfied() {
+ ServiceRegistration reg = beanFactoryReg;
+ if (reg != null) {
+ reg.unregister();
+ beanFactoryReg = null;
+ log.info("Dependencies unsatisfied. Deregistering the BeanFactory instance");
+ }
+ }
+
+ private Class getClassFromConfig(BeanConfig config) {
+ String cname = config.getClassName();
+ try {
+ return config.getClassLoader().loadClass(cname);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Could not load class for " + cname, e);
+ }
+ }
+
+ private void checkState() {
+ if (instanceMap.size() == dependencies.size()) {
+ dependenciesSatisfied();
+ } else {
+ dependenciesUnSatisfied();
+ }
+ }
+
+ private void determineDependencies(InputSource source) throws ConfigurationException, IOException {
+ Properties p = new Properties();
+ p.putAll(System.getProperties());
+ p.setProperty(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, "/fake/path");
+ RepositoryConfigurationParser parser = new RepositoryConfigurationParser(p);
+ parser.setConfigVisitor(new DepFinderBeanConfigVisitor());
+
+ try {
+ parser.parseRepositoryConfig(source);
+ } finally {
+ InputStream is = source.getByteStream();
+ if (is != null) {
+ is.close();
+ }
+ }
+
+ if (dependencies.isEmpty()) {
+ log.info("No dependencies configured. Repository would be created without any OSGi dependency getting injected");
+ return;
+ }
+
+ log.info("Following dependencies have been determined for the repository {}. Repository would be started " +
+ "once all these dependencies have been satisfied", dependencies);
+ }
+
+ private void registerInstance(Class[] depsProvided, Object o) {
+ for (Class c : depsProvided) {
+ instanceMap.put(c, o);
+ }
+ }
+
+ private void deregisterInstance(Class[] depsProvided) {
+ for (Class c : depsProvided) {
+ instanceMap.remove(c);
+ }
+ }
+
+ /**
+ * Determines all the dependencies which this ServiceReference can satisfy
+ */
+ private Class[] determineProvidedDependencies(ServiceReference ref) {
+ //Use OBJECTCLASS property from SR as that determines under what classes
+ //a given service instance is published
+ //Class[] interfaces = o.getClass().getInterfaces();
+ String[] interfaces = (String[]) ref.getProperty(Constants.OBJECTCLASS);
+ List<Class> depsProvided = new ArrayList<Class>(interfaces.length);
+ for (String intf : interfaces) {
+ if (classNameMapping.containsKey(intf)) {
+ depsProvided.add(classNameMapping.get(intf));
+ }
+ }
+ return depsProvided.toArray(new Class[depsProvided.size()]);
+ }
+
+ private void createClassNameMappings() {
+ for (Class clazz : dependencies) {
+ classNameMapping.put(clazz.getName(), clazz);
+ }
+ }
+
+ private class DepFinderBeanConfigVisitor implements BeanConfigVisitor {
+
+ public void visit(BeanConfig config) {
+ Class clazz = getClassFromConfig(config);
+ if (clazz.isInterface()) {
+ dependencies.add(clazz);
+ }
+ }
+ }
+}
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/OsgiBeanFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/config/OsgiBeanFactory.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingLoginModule.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingLoginModule.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingLoginModule.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingLoginModule.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.jcr.jackrabbit.base.security;
+
+
+import org.apache.jackrabbit.core.config.BeanConfig;
+import org.apache.jackrabbit.core.config.ConfigurationException;
+import org.apache.jackrabbit.core.config.LoginModuleConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.Configuration;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.Map;
+import java.util.Properties;
+
+public class DelegatingLoginModule implements LoginModule {
+ private static Logger logger = LoggerFactory.getLogger(DelegatingLoginModule.class);
+ public static final String JAAS_CONFIG_ALGO_NAME = "JavaLoginConfig";
+ private LoginModule delegate;
+ private LoginContext loginContext;
+ private boolean loginSucceeded;
+
+ private String appName;
+ private String delegateLoginModuleClass;
+ private String providerName;
+
+ private LoginException loginException;
+
+
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
+ Map<String, ?> options) {
+ Configuration config = null;
+ try{
+ config = Configuration.getInstance(JAAS_CONFIG_ALGO_NAME, null, providerName);
+ }catch (NoSuchProviderException e){
+ logger.debug("No provider "+providerName+"found so far",e);
+ } catch (NoSuchAlgorithmException e) {
+ logger.debug("No provider "+providerName+"found so far for fetching JAAS " +
+ "config with algorithm name "+JAAS_CONFIG_ALGO_NAME,e);
+ }
+
+ if(config != null){
+ final Thread current = Thread.currentThread();
+ final ClassLoader orig = current.getContextClassLoader();
+ try {
+ current.setContextClassLoader(DelegatingLoginModule.class.getClassLoader());
+ loginContext = new LoginContext(appName, subject,callbackHandler, config);
+ } catch (LoginException e) {
+ loginException = e;
+ } finally{
+ current.setContextClassLoader(orig);
+ }
+ }else{
+ //No support so far from OSGi so would use default logic used by Jackrabbit
+ //to construct the LoginModule
+ Properties p = new Properties();
+ p.putAll(options);
+ BeanConfig bc = new BeanConfig(delegateLoginModuleClass,p);
+ LoginModuleConfig lmc = new LoginModuleConfig(bc);
+ try {
+ delegate = lmc.getLoginModule();
+ delegate.initialize(subject,callbackHandler,sharedState,options);
+ logger.info("No JAAS Configuration provider found would be directly invoking LoginModule {}",delegateLoginModuleClass);
+ } catch (ConfigurationException e) {
+ //Behaviour is same as org.apache.jackrabbit.core.security.authentication.LocalAuthContext.login()
+ loginException = new LoginException(e.getMessage());
+ }
+ }
+ }
+
+ public boolean login() throws LoginException {
+ assertState();
+
+ if (loginContext == null) {
+ return delegate.login();
+ } else {
+ loginContext.login();
+ loginSucceeded = true;
+ return true;
+ }
+ }
+
+ public boolean commit() throws LoginException {
+ assertState();
+
+ if (loginContext == null) {
+ return delegate.commit();
+ } else {
+ return loginSucceeded;
+ }
+ }
+
+ public boolean abort() throws LoginException {
+ assertState();
+
+ if (loginContext == null) {
+ return delegate.abort();
+ } else {
+ return loginSucceeded;
+ }
+ }
+
+ public boolean logout() throws LoginException {
+ assertState();
+
+ if (loginContext == null) {
+ return delegate.logout();
+ } else {
+ loginContext.logout();
+ return true;
+ }
+ }
+
+ private void assertState() throws LoginException {
+ if(loginException != null){
+ throw loginException;
+ }
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public void setDelegateLoginModuleClass(String delegateLoginModuleClass) {
+ this.delegateLoginModuleClass = delegateLoginModuleClass;
+ }
+
+ public void setProviderName(String providerName) {
+ this.providerName = providerName;
+ }
+
+}
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingLoginModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingLoginModule.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingPrincipalProviderRegistry.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingPrincipalProviderRegistry.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingPrincipalProviderRegistry.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingPrincipalProviderRegistry.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.jcr.jackrabbit.base.security;
+
+import java.util.Properties;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
+import org.apache.jackrabbit.core.security.principal.PrincipalProviderRegistry;
+
+public class DelegatingPrincipalProviderRegistry implements PrincipalProviderRegistry {
+ private final PrincipalProviderRegistry defaultRegistry;
+ private final PrincipalProviderRegistry osgiRegistry;
+
+ public DelegatingPrincipalProviderRegistry(PrincipalProviderRegistry defaultRegistry,
+ PrincipalProviderRegistry osgiRegistry) {
+ this.defaultRegistry = defaultRegistry;
+ this.osgiRegistry = osgiRegistry;
+ }
+
+ public PrincipalProvider registerProvider(Properties properties) throws RepositoryException {
+ return defaultRegistry.registerProvider(properties);
+ }
+
+ public PrincipalProvider getDefault() {
+ return defaultRegistry.getDefault();
+ }
+
+ public PrincipalProvider getProvider(String name) {
+ PrincipalProvider p = defaultRegistry.getProvider(name);
+ if (p == null) {
+ p = osgiRegistry.getProvider(name);
+ }
+ return p;
+ }
+
+ public PrincipalProvider[] getProviders() {
+ PrincipalProvider[] defaultProviders = defaultRegistry.getProviders();
+ PrincipalProvider[] extraProviders = osgiRegistry.getProviders();
+
+ //Quick check
+ if(extraProviders.length == 0){
+ return defaultProviders;
+ }
+
+ PrincipalProvider[] mergedResult = new PrincipalProvider[defaultProviders.length + extraProviders.length];
+ System.arraycopy(defaultProviders, 0, mergedResult, 0, defaultProviders.length);
+ System.arraycopy(extraProviders, 0, mergedResult, defaultProviders.length, extraProviders.length);
+ return mergedResult;
+ }
+
+}
\ No newline at end of file
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingPrincipalProviderRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/DelegatingPrincipalProviderRegistry.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/MultiplexingAuthorizableAction.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/MultiplexingAuthorizableAction.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/MultiplexingAuthorizableAction.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/MultiplexingAuthorizableAction.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.jcr.jackrabbit.base.security;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.api.security.user.Authorizable;
+import org.apache.jackrabbit.api.security.user.Group;
+import org.apache.jackrabbit.api.security.user.User;
+import org.apache.jackrabbit.core.security.user.action.AbstractAuthorizableAction;
+import org.apache.jackrabbit.core.security.user.action.AuthorizableAction;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+
+public class MultiplexingAuthorizableAction extends AbstractAuthorizableAction implements ServiceTrackerCustomizer{
+ private Logger log = LoggerFactory.getLogger(getClass());
+
+ private Map<Comparable,AuthorizableAction> actionMap =
+ new ConcurrentSkipListMap<Comparable, AuthorizableAction>(Collections.reverseOrder());
+ private final ServiceTracker tracker;
+ private final BundleContext context;
+ private final ServiceRegistration reg;
+
+ public MultiplexingAuthorizableAction(BundleContext context){
+ this.context = context;
+ this.tracker = new ServiceTracker(context, createFilter(context),this);
+ this.tracker.open();
+
+ Properties p = new Properties();
+ p.setProperty("jackrabbit.extension","true");
+ reg = context.registerService(AuthorizableAction.class.getName(),this,p);
+ }
+
+ //~----------------------------------------<AuthorizableAction>
+
+ public void onCreate(User user, String password, Session session) throws RepositoryException {
+ log.debug("Created user {}", user.getID());
+ for(AuthorizableAction a : getActions()){
+ a.onCreate(user,password,session);
+ }
+ }
+
+ @Override
+ public void onCreate(Group group, Session session) throws RepositoryException {
+ log.debug("Created group {}", group.getID());
+ for(AuthorizableAction a : getActions()){
+ a.onCreate(group,session);
+ }
+ }
+
+ @Override
+ public void onRemove(Authorizable authorizable, Session session) throws RepositoryException {
+ log.debug("Removed authorizable {}", authorizable.getID());
+ for(AuthorizableAction a : getActions()){
+ a.onRemove(authorizable,session);
+ }
+ }
+
+ @Override
+ public void onPasswordChange(User user, String newPassword, Session session) throws RepositoryException {
+ log.debug("Password changed for user {}", user.getID());
+ for(AuthorizableAction a : getActions()){
+ a.onPasswordChange(user,newPassword,session);
+ }
+ }
+
+ //~----------------------------------------<LifeCycle methods>
+
+ public void open(){
+ tracker.open();
+ }
+
+ public void close(){
+ if(reg != null){
+ reg.unregister();
+ }
+ tracker.close();
+ actionMap.clear();
+ }
+
+ //~----------------------------------------- < ServiceTrackerCustomizer >
+
+ public Object addingService(ServiceReference reference) {
+ AuthorizableAction action = (AuthorizableAction) context.getService(reference);
+ actionMap.put(reference,action);
+ return action;
+ }
+
+ public void modifiedService(ServiceReference reference, Object service) {
+ actionMap.put(reference, (AuthorizableAction) service);
+ }
+
+ public void removedService(ServiceReference reference, Object service) {
+ actionMap.remove(reference);
+ }
+
+ private Collection<AuthorizableAction> getActions() {
+ return actionMap.values();
+ }
+
+ private Filter createFilter(BundleContext context) {
+ try {
+ //Create a filter such that we track all service excluding ourselves
+ return context.createFilter("(&(!(jackrabbit.extension=true))" +
+ "(objectClass=org.apache.jackrabbit.core.security.user.action.AuthorizableAction))");
+ } catch (InvalidSyntaxException e) {
+ //Should not happen as Filter is hardcoded and should work
+ throw new RuntimeException(e);
+ }
+ }
+}
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/MultiplexingAuthorizableAction.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/MultiplexingAuthorizableAction.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/PrincipalProviderTracker.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/PrincipalProviderTracker.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/PrincipalProviderTracker.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/PrincipalProviderTracker.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.jcr.jackrabbit.base.security;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
+import org.apache.jackrabbit.core.security.principal.PrincipalProviderRegistry;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PrincipalProviderTracker extends ServiceTracker implements PrincipalProviderRegistry{
+ /**
+ * Property-Key if the <code>PrincipalProvider</code> configured with
+ * {@link LoginModuleConfig#PARAM_PRINCIPAL_PROVIDER_CLASS} be registered using the
+ * specified name instead of the class name which is used by default if the
+ * name parameter is missing.
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/JCR-2629">JCR-2629</a>
+ */
+ private static final String COMPAT_PRINCIPAL_PROVIDER_NAME = "principal_provider.name";
+ public static final PrincipalProvider[] EMPTY_ARRAY = new PrincipalProvider[0];
+
+ private Logger log = LoggerFactory.getLogger(getClass());
+
+ private final Map<String, PrincipalProvider> providers = new ConcurrentHashMap<String, PrincipalProvider>();
+ private final Map<ServiceReference, String> refToNameMapping = new ConcurrentHashMap<ServiceReference, String>();
+ private PrincipalProvider[] providerArray = EMPTY_ARRAY;
+
+ public PrincipalProviderTracker(BundleContext context) {
+ super(context, PrincipalProvider.class.getName(), null);
+ }
+
+ //~-------------------------------------< ServiceTracker >
+
+ @Override
+ public Object addingService(ServiceReference reference) {
+ PrincipalProvider provider = (PrincipalProvider) super.addingService(reference);
+ addProvider(provider,reference);
+ reloadProviders();
+ return provider;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference reference, Object service) {
+ //Check if the name has changed then re-register the provider
+ String newName = getProviderName((PrincipalProvider) service,reference);
+ String oldName = refToNameMapping.get(reference);
+ if(!equals(newName,oldName)){
+ if(oldName != null){
+ providers.remove(oldName);
+ }
+ addProvider((PrincipalProvider) service, reference);
+ reloadProviders();
+ }
+ }
+
+ @Override
+ public void removedService(ServiceReference reference, Object service) {
+ String name = refToNameMapping.remove(reference);
+ if(name != null){
+ providers.remove(name);
+ }
+ reloadProviders();
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ providers.clear();
+ refToNameMapping.clear();
+ providerArray = EMPTY_ARRAY;
+ }
+
+ //~-------------------------------------< PrincipalProviderRegistry >
+
+ public PrincipalProvider registerProvider(Properties configuration) throws RepositoryException {
+ throw new UnsupportedOperationException("The PrincipalProvider are only registered as OSGi services");
+ }
+
+ public PrincipalProvider getDefault() {
+ throw new UnsupportedOperationException("Default provider is handled via WorkspaceBasedPrincipalProviderRegistry");
+ }
+
+ public PrincipalProvider getProvider(String className) {
+ return providers.get(className);
+ }
+
+ public PrincipalProvider[] getProviders() {
+ return providerArray;
+ }
+
+ private void addProvider(PrincipalProvider provider,ServiceReference reference){
+ String providerName = getProviderName(provider,reference);
+ if(providers.containsKey(providerName)){
+ log.warn("Provider with name {} is already registered. PrincipalProvider {} " +
+ "would not be registered",providerName,reference);
+ return;
+ }
+ providers.put(providerName,provider);
+ refToNameMapping.put(reference,providerName);
+ }
+
+ private void reloadProviders() {
+ PrincipalProvider[] providerArray = providers.values().toArray(new PrincipalProvider[providers.size()]);
+ synchronized (this){
+ this.providerArray = providerArray;
+ }
+ }
+
+ private static String getProviderName(PrincipalProvider provider,ServiceReference ref){
+ String providerName = (String) ref.getProperty(COMPAT_PRINCIPAL_PROVIDER_NAME);
+ if(providerName == null){
+ providerName = provider.getClass().getName();
+ }
+ return providerName;
+ }
+
+ private static boolean equals(Object object1, Object object2) {
+ if (object1 == object2) {
+ return true;
+ }
+ if ((object1 == null) || (object2 == null)) {
+ return false;
+ }
+ return object1.equals(object2);
+ }
+
+}
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/PrincipalProviderTracker.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/PrincipalProviderTracker.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/package-info.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/package-info.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/package-info.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * Provides support for performing JAAS based authentication in OSGi
+ *
+ * @version 1.0
+ */
+@Version("1.0")
+@Export(optional = "provide:=true")
+package org.apache.sling.jcr.jackrabbit.base.security;
+
+import aQute.bnd.annotation.Export;
+import aQute.bnd.annotation.Version;
\ No newline at end of file
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/package-info.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-base/src/main/java/org/apache/sling/jcr/jackrabbit/base/security/package-info.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Modified: sling/trunk/bundles/jcr/jackrabbit-server/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-server/pom.xml?rev=1401220&r1=1401219&r2=1401220&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-server/pom.xml (original)
+++ sling/trunk/bundles/jcr/jackrabbit-server/pom.xml Tue Oct 23 09:40:15 2012
@@ -97,7 +97,10 @@
org.apache.sling.jcr.jackrabbit.server;version=2.1.0,
org.apache.sling.jcr.jackrabbit.server.security;version=2.0.4-incubator,
org.apache.sling.jcr.jackrabbit.server.security.accessmanager;version=2.1.0,
- org.apache.jackrabbit.core.security.principal;version=2.2.5
+ org.apache.jackrabbit.core.security.principal;version=2.2.5,
+ org.apache.jackrabbit.core.security.authentication;version=2.2.5,
+ org.apache.jackrabbit.core.security.authentication.token;version=2.2.5,
+ org.apache.jackrabbit.core.security.user.action;version=2.4.0
</Export-Package>
<Private-Package>
org.apache.sling.jcr.jackrabbit.server.impl.*,
@@ -137,6 +140,8 @@
org.apache.jackrabbit.commons.*,
org.apache.jackrabbit.spi.commons.*,
+ org.apache.felix.jaas.boot;resolution:=optional,
+
<!-- optional JDBC driver import -->
com.microsoft.sqlserver.jdbc;
oracle.jdbc;
@@ -155,11 +160,17 @@
<Embed-Transitive>true</Embed-Transitive>
<Embed-Dependency>
jackrabbit-core,
+ org.apache.sling.jcr.jackrabbit.base,
lucene-core,
concurrent,
commons-dbcp,
commons-pool
</Embed-Dependency>
+ <Jaas-ModuleClass>
+ org.apache.jackrabbit.core.security.authentication.DefaultLoginModule,
+ org.apache.jackrabbit.core.security.simple.SimpleLoginModule,
+ org.apache.sling.jcr.jackrabbit.server.security.SlingDefaultLoginModule
+ </Jaas-ModuleClass>
<_removeheaders>
Embed-Dependency,
Embed-Transitive,
@@ -200,6 +211,12 @@
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.jackrabbit.base</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.jcr.base</artifactId>
<version>2.1.0</version>
<scope>compile</scope>
@@ -215,7 +232,7 @@
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-core</artifactId>
- <version>2.4.2</version>
+ <version>2.5.2</version>
<scope>compile</scope>
</dependency>
Modified: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/Activator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/Activator.java?rev=1401220&r1=1401219&r2=1401220&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/Activator.java (original)
+++ sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/Activator.java Tue Oct 23 09:40:15 2012
@@ -17,14 +17,19 @@
package org.apache.sling.jcr.jackrabbit.server.impl;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.sling.jcr.base.AbstractSlingRepository;
import org.apache.sling.jcr.base.util.RepositoryAccessor;
+import org.apache.sling.jcr.jackrabbit.base.config.OsgiBeanFactory;
+import org.apache.sling.jcr.jackrabbit.base.security.MultiplexingAuthorizableAction;
+import org.apache.sling.jcr.jackrabbit.base.security.PrincipalProviderTracker;
import org.apache.sling.jcr.jackrabbit.server.security.LoginModulePlugin;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
@@ -38,6 +43,7 @@ import org.osgi.service.cm.Configuration
import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.xml.sax.InputSource;
/**
* The <code>Activator</code> TODO
@@ -84,6 +90,12 @@ public class Activator implements Bundle
private String slingContext;
private static AccessManagerFactoryTracker accessManagerFactoryTracker;
+ private static PrincipalProviderTracker principalProviderTracker;
+
+ private OsgiBeanFactory beanFactory;
+
+ private MultiplexingAuthorizableAction authorizableActionTracker;
+
protected String getRepositoryName() {
String repoName = bundleContext.getProperty("sling.repository.name");
if (repoName != null) {
@@ -129,6 +141,16 @@ public class Activator implements Bundle
accessManagerFactoryTracker = new AccessManagerFactoryTracker(bundleContext);
}
accessManagerFactoryTracker.open();
+
+ if(principalProviderTracker == null){
+ principalProviderTracker = new PrincipalProviderTracker(bundleContext);
+ }
+ principalProviderTracker.open();
+
+ if(authorizableActionTracker == null){
+ authorizableActionTracker = new MultiplexingAuthorizableAction(bundleContext);
+ }
+ authorizableActionTracker.open();
}
public void stop(BundleContext arg0) {
@@ -147,6 +169,21 @@ public class Activator implements Bundle
accessManagerFactoryTracker = null;
}
+ if(principalProviderTracker != null){
+ principalProviderTracker.close();
+ principalProviderTracker = null;
+ }
+
+ if(beanFactory != null){
+ beanFactory.close();
+ beanFactory = null;
+ }
+
+ if(authorizableActionTracker != null){
+ authorizableActionTracker.close();
+ authorizableActionTracker = null;
+ }
+
// clear the bundle context field
bundleContext = null;
}
@@ -210,6 +247,10 @@ public class Activator implements Bundle
return accessManagerFactoryTracker;
}
+ public static PrincipalProviderTracker getPrincipalProviderTracker(){
+ return principalProviderTracker;
+ }
+
// ---------- internal -----------------------------------------------------
private void verifyConfiguration(ServiceReference ref) {
@@ -229,6 +270,7 @@ public class Activator implements Bundle
"verifyConfiguration: {} Configurations available for {}, nothing to do",
new Object[] { new Integer(cfgs.length),
SERVER_REPOSITORY_FACTORY_PID });
+ createBeanFactory(cfgs[0]);
return;
}
@@ -248,7 +290,7 @@ public class Activator implements Bundle
// create the factory and set the properties
Configuration config = ca.createFactoryConfiguration(SERVER_REPOSITORY_FACTORY_PID);
config.update(defaultConfig);
-
+ createBeanFactory(config);
log.info("verifyConfiguration: Created configuration {} for {}",
config.getPid(), config.getFactoryPid());
@@ -260,6 +302,47 @@ public class Activator implements Bundle
}
}
+ /**
+ * Creates the BeanFactory by finding out the location of repository
+ * configuration. Currently it depends on internal of SlingServerRepository implementation on how it accesses the
+ * repository configuration.
+ *
+ * TODO - Find a better way to centralize logic related to configuration access
+ */
+ private void createBeanFactory(Configuration c){
+ InputSource source = null;
+ try {
+ Dictionary config = c.getProperties();
+ String home = (String) config.get(SlingServerRepository.REPOSITORY_HOME_DIR);
+
+ //1. Check override url
+ String configUrl = (String) config.get(RepositoryAccessor.REPOSITORY_URL_OVERRIDE_PROPERTY);
+
+ //2. Check default url
+ if(configUrl == null){
+ configUrl = (String) config.get(SlingServerRepository.REPOSITORY_CONFIG_URL);
+ }
+
+ //If url found create InputSource from it else
+ //point to repository home director
+ if(configUrl != null){
+ source = new InputSource(new FileInputStream(new File(configUrl)));
+ }else if(home != null){
+ String homePath = SlingServerRepository.getAbsoluteHomePath(config,bundleContext);
+ source = SlingServerRepository.getRepositoryConfigSource(new File(homePath));
+ }
+
+ if(source == null){
+ throw new IllegalStateException("Cannot determine repository configuration file location");
+ }
+
+ beanFactory = new OsgiBeanFactory(bundleContext);
+ beanFactory.initialize(source);
+ } catch (Exception e) {
+ throw new RuntimeException("Error occurred while initializing bean factory",e);
+ }
+ }
+
private void initDefaultConfig(Hashtable<String, String> props, BundleContext bundleContext) throws IOException {
String slingHomePath = bundleContext.getProperty("sling.home");
String home = getHomePath(bundleContext, slingHomePath);
Modified: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/SlingServerRepository.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/SlingServerRepository.java?rev=1401220&r1=1401219&r2=1401220&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/SlingServerRepository.java (original)
+++ sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/SlingServerRepository.java Tue Oct 23 09:40:15 2012
@@ -35,10 +35,14 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
import org.apache.jackrabbit.api.management.DataStoreGarbageCollector;
import org.apache.jackrabbit.api.management.RepositoryManager;
import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.BeanFactory;
+import org.apache.jackrabbit.core.config.ConfigurationException;
import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.base.AbstractSlingRepository;
import org.apache.sling.jcr.jackrabbit.server.impl.security.AdministrativeCredentials;
@@ -47,6 +51,7 @@ import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.log.LogService;
+import org.xml.sax.InputSource;
/**
* The <code>SlingServerRepository</code> TODO
@@ -90,6 +95,9 @@ public class SlingServerRepository exten
@Property(value="")
public static final String REPOSITORY_REGISTRATION_NAME = "name";
+ @Reference
+ private BeanFactory beanFactory;
+
//---------- Repository Management ----------------------------------------
@Override
@@ -102,21 +110,8 @@ public class SlingServerRepository exten
@SuppressWarnings("unchecked")
Dictionary<String, Object> environment = this.getComponentContext().getProperties();
String configURLObj = (String) environment.get(REPOSITORY_CONFIG_URL);
- String home = (String) environment.get(REPOSITORY_HOME_DIR);
-
- // ensure absolute home (path)
+ String home = getAbsoluteHomePath(environment,getComponentContext().getBundleContext());
File homeFile = new File(home);
- if (!homeFile.isAbsolute()) {
- BundleContext context = getComponentContext().getBundleContext();
- String slingHomePath = context.getProperty("sling.home");
- if (slingHomePath != null) {
- homeFile = new File(slingHomePath, home);
- } else {
- homeFile = homeFile.getAbsoluteFile();
- }
- home = homeFile.getAbsolutePath();
- }
-
// somewhat dirty hack to have the derby.log file in a sensible
// location, but don't overwrite anything already set
if (System.getProperty("derby.stream.error.file") == null) {
@@ -157,9 +152,9 @@ public class SlingServerRepository exten
log(LogService.LOG_INFO, "Using configuration file " + configFile.getAbsolutePath());
}
}
- crc = RepositoryConfig.create(ins, home);
+ crc = create(new InputSource(ins), homeFile);
} else {
- crc = RepositoryConfig.create(homeFile);
+ crc = create(getRepositoryConfigSource(homeFile), homeFile);
}
return RepositoryImpl.create(crc);
@@ -189,6 +184,7 @@ public class SlingServerRepository exten
return null;
}
+
@Override
protected void disposeRepository(Repository repository) {
super.disposeRepository(repository);
@@ -303,6 +299,27 @@ public class SlingServerRepository exten
}
}
+ public static String getAbsoluteHomePath(Dictionary<String, Object> p,BundleContext context){
+ String home = (String) p.get(REPOSITORY_HOME_DIR);
+
+ // ensure absolute home (path)
+ File homeFile = new File(home);
+ if (!homeFile.isAbsolute()) {
+ String slingHomePath = context.getProperty("sling.home");
+ if (slingHomePath != null) {
+ homeFile = new File(slingHomePath, home);
+ } else {
+ homeFile = homeFile.getAbsoluteFile();
+ }
+ home = homeFile.getAbsolutePath();
+ }
+ return home;
+ }
+
+ public static InputSource getRepositoryConfigSource(File homeFile) throws FileNotFoundException {
+ return new InputSource(new FileInputStream(new File(homeFile, "repository.xml")));
+ }
+
/**
* {@inheritDoc}
* @see org.apache.sling.jcr.base.AbstractSlingRepository#getAdministrativeCredentials(java.lang.String)
@@ -320,4 +337,16 @@ public class SlingServerRepository exten
protected Credentials getAnonCredentials(String anonUser) {
return new AnonCredentials(anonUser);
}
+
+ private RepositoryConfig create(InputSource xml, File dir) throws ConfigurationException {
+ java.util.Properties variables = new java.util.Properties(System.getProperties());
+ variables.setProperty(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE, dir.getPath());
+ RepositoryConfigurationParser parser =
+ new RepositoryConfigurationParser(variables);
+ parser.setBeanFactory(beanFactory);
+ RepositoryConfig config = parser.parseRepositoryConfig(xml);
+ config.init();
+ return config;
+ }
+
}
Added: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.jcr.jackrabbit.server.impl.security;
+
+import org.apache.jackrabbit.core.DefaultSecurityManager;
+import org.apache.jackrabbit.core.security.principal.PrincipalProviderRegistry;
+import org.apache.sling.jcr.jackrabbit.base.security.DelegatingPrincipalProviderRegistry;
+import org.apache.sling.jcr.jackrabbit.server.impl.Activator;
+
+/**
+ * User: chetanm
+ * Date: 16/10/12
+ * Time: 7:57 PM
+ */
+public class OsgiAwareSecurityManager extends DefaultSecurityManager {
+
+ @Override
+ protected PrincipalProviderRegistry getPrincipalProviderRegistry() {
+ PrincipalProviderRegistry defaultRegistry = super.getPrincipalProviderRegistry();
+ PrincipalProviderRegistry osgiRegistry = Activator.getPrincipalProviderTracker();
+ if(osgiRegistry != null){
+ return new DelegatingPrincipalProviderRegistry(defaultRegistry,osgiRegistry);
+ }
+ return defaultRegistry;
+ }
+
+}
Propchange: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/OsgiAwareSecurityManager.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/TrustedCredentials.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/TrustedCredentials.java?rev=1401220&r1=1401219&r2=1401220&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/TrustedCredentials.java (original)
+++ sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/impl/security/TrustedCredentials.java Tue Oct 23 09:40:15 2012
@@ -71,7 +71,7 @@ public abstract class TrustedCredentials
/**
* @return
*/
- protected Authentication getTrustedAuthentication() {
+ public Authentication getTrustedAuthentication() {
return authentication;
}
Added: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java?rev=1401220&view=auto
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java (added)
+++ sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java Tue Oct 23 09:40:15 2012
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.jcr.jackrabbit.server.security;
+
+import org.apache.jackrabbit.core.security.authentication.Authentication;
+import org.apache.jackrabbit.core.security.authentication.CredentialsCallback;
+import org.apache.jackrabbit.core.security.authentication.DefaultLoginModule;
+import org.apache.sling.jcr.jackrabbit.server.impl.security.AdministrativeCredentials;
+import org.apache.sling.jcr.jackrabbit.server.impl.security.AnonCredentials;
+import org.apache.sling.jcr.jackrabbit.server.impl.security.CallbackHandlerWrapper;
+import org.apache.sling.jcr.jackrabbit.server.impl.security.TrustedCredentials;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Credentials;
+import javax.jcr.RepositoryException;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.login.FailedLoginException;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Map;
+
+/**
+ * User: chetanm
+ * Date: 9/9/12
+ * Time: 2:45 AM
+ */
+public class SlingDefaultLoginModule extends DefaultLoginModule{
+ private static final Logger log = LoggerFactory.getLogger(SlingDefaultLoginModule.class);
+ /**
+ * captured call back hander in use.
+ */
+ private CallbackHandler pluggableCallackHander;
+ @Override
+ protected Principal getPrincipal(Credentials creds) {
+ if ( creds instanceof TrustedCredentials) {
+ return ((TrustedCredentials) creds).getPrincipal();
+ }
+ return super.getPrincipal(creds);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.apache.jackrabbit.core.security.authentication.AbstractLoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
+ */
+ @Override
+ public void initialize(Subject subject, CallbackHandler callbackHandler,
+ Map<String, ?> sharedState, Map<String, ?> options) {
+ CallbackHandlerWrapper wrappedCallbackHandler = new CallbackHandlerWrapper(subject, callbackHandler);
+ this.pluggableCallackHander = callbackHandler;
+ super.initialize(subject, wrappedCallbackHandler, sharedState, options);
+ }
+
+ @Override
+ protected Authentication getAuthentication(Principal principal, Credentials creds) throws RepositoryException {
+ if ( creds instanceof TrustedCredentials ) {
+ return ((TrustedCredentials) creds).getTrustedAuthentication();
+ }
+ return super.getAuthentication(principal, creds);
+ }
+
+ /**
+ * Since the AbstractLoginModule getCredentials does not know anything about TrustedCredentials we have to re-try here.
+ */
+ @Override
+ protected Credentials getCredentials() {
+ Credentials creds = super.getCredentials();
+ if ( creds == null ) {
+ CredentialsCallback callback = new CredentialsCallback();
+ try {
+ pluggableCallackHander.handle(new Callback[]{callback});
+ Credentials callbackCreds = callback.getCredentials();
+ if ( callbackCreds instanceof TrustedCredentials ) {
+ creds = callbackCreds;
+ }
+ } catch (UnsupportedCallbackException e) {
+ log.warn("Credentials-Callback not supported try Name-Callback");
+ } catch (IOException e) {
+ log.error("Credentials-Callback failed: " + e.getMessage() + ": try Name-Callback");
+ }
+ }
+ return creds;
+ }
+
+ @Override
+ protected boolean impersonate(Principal principal, Credentials creds) throws RepositoryException, FailedLoginException {
+ if ( creds instanceof AdministrativeCredentials) {
+ return true;
+ }
+ if ( creds instanceof AnonCredentials) {
+ return false;
+ }
+
+ return super.impersonate(principal, creds);
+ }
+
+ @Override
+ protected boolean supportsCredentials(Credentials creds) {
+ if (creds instanceof TrustedCredentials) {
+ return true;
+ }
+ return super.supportsCredentials(creds);
+ }
+}
Propchange: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: sling/trunk/bundles/jcr/jackrabbit-server/src/main/java/org/apache/sling/jcr/jackrabbit/server/security/SlingDefaultLoginModule.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml?rev=1401220&r1=1401219&r2=1401220&view=diff
==============================================================================
--- sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml (original)
+++ sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml Tue Oct 23 09:40:15 2012
@@ -18,8 +18,8 @@
under the License.
-->
<!DOCTYPE Repository
- PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 2.0//EN"
- "http://jackrabbit.apache.org/dtd/repository-2.0.dtd">
+ PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit 2.4//EN"
+ "http://jackrabbit.apache.org/dtd/repository-2.4.dtd">
<Repository>
<FileSystem class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
@@ -30,6 +30,11 @@
<Security appName="Jackrabbit">
<SecurityManager class="org.apache.jackrabbit.core.DefaultSecurityManager" workspaceName="security">
+ <UserManager class="org.apache.jackrabbit.core.security.user.UserManagerImpl">
+ <param name="defaultDepth" value="1"/>
+ <param name="autoExpandTree" value="true"/>
+ <AuthorizableAction class="org.apache.jackrabbit.core.security.user.action.AuthorizableAction" />
+ </UserManager>
</SecurityManager>
<AccessManager class="org.apache.sling.jcr.jackrabbit.server.impl.security.PluggableDefaultAccessManager">
Modified: sling/trunk/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/pom.xml?rev=1401220&r1=1401219&r2=1401220&view=diff
==============================================================================
--- sling/trunk/pom.xml (original)
+++ sling/trunk/pom.xml Tue Oct 23 09:40:15 2012
@@ -136,6 +136,7 @@
<module>bundles/jcr/base</module>
<module>bundles/jcr/classloader</module>
<module>bundles/jcr/contentloader</module>
+ <module>bundles/jcr/jackrabbit-base</module>
<module>bundles/jcr/jackrabbit-server</module>
<module>bundles/jcr/jackrabbit-usermanager</module>
<module>bundles/jcr/jackrabbit-accessmanager</module>