From: Bruno Sinou Date: Thu, 15 Sep 2016 17:50:32 +0000 (+0000) Subject: Move APIs, clean base bundles X-Git-Tag: argeo-commons-2.1.46~18 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=85688af22a77f82e7762e11e6eb38c6367eddb6c;p=lgpl%2Fargeo-commons.git Move APIs, clean base bundles git-svn-id: https://svn.argeo.org/commons/trunk@9168 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/dep/org.argeo.dep.cms.platform/pom.xml b/dep/org.argeo.dep.cms.platform/pom.xml index 120e68642..43b34a84a 100644 --- a/dep/org.argeo.dep.cms.platform/pom.xml +++ b/dep/org.argeo.dep.cms.platform/pom.xml @@ -32,6 +32,11 @@ org.argeo.cms.ui.workbench 2.1.46-SNAPSHOT + + org.argeo.commons + org.argeo.cms.ui.workbench.rap + 2.1.46-SNAPSHOT + diff --git a/org.argeo.cms.ui/bnd.bnd b/org.argeo.cms.ui/bnd.bnd index e472a2c52..facde000f 100644 --- a/org.argeo.cms.ui/bnd.bnd +++ b/org.argeo.cms.ui/bnd.bnd @@ -6,6 +6,4 @@ org.eclipse.jface.window,\ org.eclipse.core.commands,\ javax.jcr.security,\ org.argeo.eclipse.ui.dialogs,\ -org.springframework.context,\ -org.springframework.core.io,\ * \ No newline at end of file diff --git a/org.argeo.cms.ui/src/org/argeo/security/core/AbstractSystemExecution.java b/org.argeo.cms.ui/src/org/argeo/security/core/AbstractSystemExecution.java deleted file mode 100644 index 9c3e5cd83..000000000 --- a/org.argeo.cms.ui/src/org/argeo/security/core/AbstractSystemExecution.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * 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.security.core; - -import javax.security.auth.Subject; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; - -/** Provides base method for executing code with system authorization. */ -public abstract class AbstractSystemExecution { - private final static Log log = LogFactory.getLog(AbstractSystemExecution.class); - private final Subject subject = new Subject(); - - private final String loginModule = "SYSTEM"; - - /** - * Authenticate the calling thread to the underlying - * {@link AuthenticationManager} - */ - protected void authenticateAsSystem() { - ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - try { - LoginContext lc = new LoginContext(loginModule, subject); - lc.login(); - } catch (LoginException e) { - throw new CmsException("Cannot login as system", e); - } finally { - Thread.currentThread().setContextClassLoader(origClassLoader); - } - if (log.isTraceEnabled()) - log.trace("System authenticated"); - } - - protected void deauthenticateAsSystem() { - ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); - try { - LoginContext lc = new LoginContext(loginModule, subject); - lc.logout(); - } catch (LoginException e) { - throw new CmsException("Cannot logout as system", e); - } finally { - Thread.currentThread().setContextClassLoader(origClassLoader); - } - } - - protected Subject getSubject() { - return subject; - } -} diff --git a/org.argeo.cms.ui/src/org/argeo/security/core/AuthenticatedApplicationContextInitialization.java b/org.argeo.cms.ui/src/org/argeo/security/core/AuthenticatedApplicationContextInitialization.java deleted file mode 100644 index aa3827c92..000000000 --- a/org.argeo.cms.ui/src/org/argeo/security/core/AuthenticatedApplicationContextInitialization.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * 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.security.core; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.List; - -import javax.security.auth.Subject; - -import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.support.AbstractBeanFactory; -import org.springframework.beans.factory.support.SecurityContextProvider; -import org.springframework.beans.factory.support.SimpleSecurityContextProvider; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -/** - * Executes with a system authentication the instantiation and initialization - * methods of the application context where it has been defined. - */ -public class AuthenticatedApplicationContextInitialization extends - AbstractSystemExecution implements - DependencyInitializationAwareBeanPostProcessor, ApplicationContextAware { - /** If non empty, restricts to these beans */ - private List beanNames = new ArrayList(); - - public Object postProcessBeforeInitialization(Object bean, String beanName) - throws BeansException { - if (beanNames.size() == 0 || beanNames.contains(beanName)) - authenticateAsSystem(); - return bean; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) - throws BeansException { - if (beanNames.size() == 0 || beanNames.contains(beanName)) - deauthenticateAsSystem(); - return bean; - } - - public void setBeanNames(List beanNames) { - this.beanNames = beanNames; - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - if (applicationContext.getAutowireCapableBeanFactory() instanceof AbstractBeanFactory) { - final AbstractBeanFactory beanFactory = ((AbstractBeanFactory) applicationContext - .getAutowireCapableBeanFactory()); - // retrieve subject's access control context - // and set it as the bean factory security context - Subject.doAs(getSubject(), new PrivilegedAction() { - @Override - public Void run() { - SecurityContextProvider scp = new SimpleSecurityContextProvider( - AccessController.getContext()); - beanFactory.setSecurityContextProvider(scp); - return null; - } - }); - } - } -} diff --git a/org.argeo.cms.ui/src/org/argeo/security/core/OsgiModuleLabel.java b/org.argeo.cms.ui/src/org/argeo/security/core/OsgiModuleLabel.java deleted file mode 100644 index 45c9e16b0..000000000 --- a/org.argeo.cms.ui/src/org/argeo/security/core/OsgiModuleLabel.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.argeo.security.core; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; - -/** - * Logs the name and version of an OSGi bundle based on its - * {@link BundleContext}. - */ -public class OsgiModuleLabel { - private final static Log log = LogFactory.getLog(OsgiModuleLabel.class); - - private Bundle bundle; - - public OsgiModuleLabel() { - } - - /** Sets without logging. */ - public OsgiModuleLabel(Bundle bundle) { - this.bundle = bundle; - } - - /** - * Retrieved bundle from a bundle context and logs it. Typically to be set - * as a Spring bean. - */ - public void setBundleContext(BundleContext bundleContext) { - this.bundle = bundleContext.getBundle(); - log.info(msg()); - } - - public String msg() { - String name = bundle.getHeaders().get(Constants.BUNDLE_NAME).toString(); - String symbolicName = bundle.getSymbolicName(); - String version = bundle.getVersion().toString(); - return name + " v" + version + " (" + symbolicName + ")"; - } -} diff --git a/org.argeo.cms.ui/src/org/argeo/security/core/SimpleRoleRegistration.java b/org.argeo.cms.ui/src/org/argeo/security/core/SimpleRoleRegistration.java deleted file mode 100644 index 58f6686ac..000000000 --- a/org.argeo.cms.ui/src/org/argeo/security/core/SimpleRoleRegistration.java +++ /dev/null @@ -1,89 +0,0 @@ -package org.argeo.security.core; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.transaction.UserTransaction; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.cms.CmsException; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.UserAdmin; - -/** - * Register one or many roles via a user admin service. Does nothing if the role - * is already registered. - */ -public class SimpleRoleRegistration implements Runnable { - private final static Log log = LogFactory - .getLog(SimpleRoleRegistration.class); - - private String role; - private List roles = new ArrayList(); - private UserAdmin userAdmin; - private UserTransaction userTransaction; - - @Override - public void run() { - try { - userTransaction.begin(); - if (role != null && !roleExists(role)) - newRole(toDn(role)); - - for (String r : roles) - if (!roleExists(r)) - newRole(toDn(r)); - userTransaction.commit(); - } catch (Exception e) { - try { - userTransaction.rollback(); - } catch (Exception e1) { - log.error("Cannot rollback", e1); - } - throw new CmsException("Cannot add roles", e); - } - } - - private boolean roleExists(String role) { - return userAdmin.getRole(toDn(role).toString()) != null; - } - - protected void newRole(LdapName r) { - userAdmin.createRole(r.toString(), Role.GROUP); - log.info("Added role " + r + " required by application."); - } - - public void register(UserAdmin userAdminService, Map properties) { - this.userAdmin = userAdminService; - run(); - } - - protected LdapName toDn(String name) { - try { - return new LdapName("cn=" + name + ",ou=roles,ou=node"); - } catch (InvalidNameException e) { - throw new CmsException("Badly formatted role name " + name, e); - } - } - - public void setRole(String role) { - this.role = role; - } - - public void setRoles(List roles) { - this.roles = roles; - } - - public void setUserAdmin(UserAdmin userAdminService) { - this.userAdmin = userAdminService; - } - - public void setUserTransaction(UserTransaction userTransaction) { - this.userTransaction = userTransaction; - } - -} diff --git a/org.argeo.cms/bnd.bnd b/org.argeo.cms/bnd.bnd index 822bdd059..b638bb21b 100644 --- a/org.argeo.cms/bnd.bnd +++ b/org.argeo.cms/bnd.bnd @@ -6,5 +6,7 @@ org.postgresql;resolution:=optional,\ org.apache.jackrabbit.webdav.server,\ org.apache.jackrabbit.webdav.jcr,\ org.eclipse.equinox.http.jetty,\ +org.springframework.context,\ +org.springframework.core.io,\ * Provide-Capability: cms.datamodel;name=cms;cnd=/org/argeo/cms/cms.cnd;abstract=true \ No newline at end of file diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java index 9908e9772..a9b30681b 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java @@ -19,10 +19,10 @@ import javax.naming.ldap.Rdn; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; +import org.argeo.naming.AttributesDictionary; +import org.argeo.naming.LdifParser; +import org.argeo.naming.LdifWriter; import org.argeo.node.NodeConstants; -import org.argeo.util.naming.AttributesDictionary; -import org.argeo.util.naming.LdifParser; -import org.argeo.util.naming.LdifWriter; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.service.cm.Configuration; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeDeployConfig.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeDeployConfig.java index 85906b092..3cfb8db91 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeDeployConfig.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeDeployConfig.java @@ -18,11 +18,11 @@ import javax.naming.directory.Attributes; import javax.naming.ldap.LdapName; import org.argeo.cms.CmsException; +import org.argeo.naming.AttributesDictionary; +import org.argeo.naming.LdifParser; +import org.argeo.naming.LdifWriter; import org.argeo.node.NodeConstants; import org.argeo.node.RepoConf; -import org.argeo.util.naming.AttributesDictionary; -import org.argeo.util.naming.LdifParser; -import org.argeo.util.naming.LdifWriter; class NodeDeployConfig { private final String BASE = "ou=deploy,ou=node"; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg index 88b2cd8e4..269c9112b 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg @@ -28,7 +28,7 @@ HARDENED_KERNEL { }; KEYRING { - org.argeo.util.security.KeyringLoginModule required; + org.argeo.cms.auth.KeyringLoginModule required; }; SINGLE_USER { diff --git a/org.argeo.cms/src/org/argeo/cms/spring/AbstractSystemExecution.java b/org.argeo.cms/src/org/argeo/cms/spring/AbstractSystemExecution.java new file mode 100644 index 000000000..a7297ef36 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/spring/AbstractSystemExecution.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * 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.cms.spring; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; + +/** Provides base method for executing code with system authorization. */ +abstract class AbstractSystemExecution { + private final static Log log = LogFactory.getLog(AbstractSystemExecution.class); + private final Subject subject = new Subject(); + + private final String loginModule = "SYSTEM"; + + /** + * Authenticate the calling thread to the underlying + * {@link AuthenticationManager} + */ + protected void authenticateAsSystem() { + ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + try { + LoginContext lc = new LoginContext(loginModule, subject); + lc.login(); + } catch (LoginException e) { + throw new CmsException("Cannot login as system", e); + } finally { + Thread.currentThread().setContextClassLoader(origClassLoader); + } + if (log.isTraceEnabled()) + log.trace("System authenticated"); + } + + protected void deauthenticateAsSystem() { + ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); + try { + LoginContext lc = new LoginContext(loginModule, subject); + lc.logout(); + } catch (LoginException e) { + throw new CmsException("Cannot logout as system", e); + } finally { + Thread.currentThread().setContextClassLoader(origClassLoader); + } + } + + protected Subject getSubject() { + return subject; + } +} diff --git a/org.argeo.cms/src/org/argeo/cms/spring/AuthenticatedApplicationContextInitialization.java b/org.argeo.cms/src/org/argeo/cms/spring/AuthenticatedApplicationContextInitialization.java new file mode 100644 index 000000000..e1af58274 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/spring/AuthenticatedApplicationContextInitialization.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * 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.cms.spring; + +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.List; + +import javax.security.auth.Subject; + +import org.eclipse.gemini.blueprint.context.DependencyInitializationAwareBeanPostProcessor; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.support.AbstractBeanFactory; +import org.springframework.beans.factory.support.SecurityContextProvider; +import org.springframework.beans.factory.support.SimpleSecurityContextProvider; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * Executes with a system authentication the instantiation and initialization + * methods of the application context where it has been defined. + */ +public class AuthenticatedApplicationContextInitialization extends + AbstractSystemExecution implements + DependencyInitializationAwareBeanPostProcessor, ApplicationContextAware { + /** If non empty, restricts to these beans */ + private List beanNames = new ArrayList(); + + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + if (beanNames.size() == 0 || beanNames.contains(beanName)) + authenticateAsSystem(); + return bean; + } + + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + if (beanNames.size() == 0 || beanNames.contains(beanName)) + deauthenticateAsSystem(); + return bean; + } + + public void setBeanNames(List beanNames) { + this.beanNames = beanNames; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) + throws BeansException { + if (applicationContext.getAutowireCapableBeanFactory() instanceof AbstractBeanFactory) { + final AbstractBeanFactory beanFactory = ((AbstractBeanFactory) applicationContext + .getAutowireCapableBeanFactory()); + // retrieve subject's access control context + // and set it as the bean factory security context + Subject.doAs(getSubject(), new PrivilegedAction() { + @Override + public Void run() { + SecurityContextProvider scp = new SimpleSecurityContextProvider( + AccessController.getContext()); + beanFactory.setSecurityContextProvider(scp); + return null; + } + }); + } + } +} diff --git a/org.argeo.cms/src/org/argeo/cms/spring/SimpleRoleRegistration.java b/org.argeo.cms/src/org/argeo/cms/spring/SimpleRoleRegistration.java new file mode 100644 index 000000000..255ce111c --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/spring/SimpleRoleRegistration.java @@ -0,0 +1,89 @@ +package org.argeo.cms.spring; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.CmsException; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.UserAdmin; + +/** + * Register one or many roles via a user admin service. Does nothing if the role + * is already registered. + */ +public class SimpleRoleRegistration implements Runnable { + private final static Log log = LogFactory + .getLog(SimpleRoleRegistration.class); + + private String role; + private List roles = new ArrayList(); + private UserAdmin userAdmin; + private UserTransaction userTransaction; + + @Override + public void run() { + try { + userTransaction.begin(); + if (role != null && !roleExists(role)) + newRole(toDn(role)); + + for (String r : roles) + if (!roleExists(r)) + newRole(toDn(r)); + userTransaction.commit(); + } catch (Exception e) { + try { + userTransaction.rollback(); + } catch (Exception e1) { + log.error("Cannot rollback", e1); + } + throw new CmsException("Cannot add roles", e); + } + } + + private boolean roleExists(String role) { + return userAdmin.getRole(toDn(role).toString()) != null; + } + + protected void newRole(LdapName r) { + userAdmin.createRole(r.toString(), Role.GROUP); + log.info("Added role " + r + " required by application."); + } + + public void register(UserAdmin userAdminService, Map properties) { + this.userAdmin = userAdminService; + run(); + } + + protected LdapName toDn(String name) { + try { + return new LdapName("cn=" + name + ",ou=roles,ou=node"); + } catch (InvalidNameException e) { + throw new CmsException("Badly formatted role name " + name, e); + } + } + + public void setRole(String role) { + this.role = role; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + public void setUserAdmin(UserAdmin userAdminService) { + this.userAdmin = userAdminService; + } + + public void setUserTransaction(UserTransaction userTransaction) { + this.userTransaction = userTransaction; + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/spring/osgi/OsgiModuleLabel.java b/org.argeo.cms/src/org/argeo/cms/spring/osgi/OsgiModuleLabel.java new file mode 100644 index 000000000..f085d6a23 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/spring/osgi/OsgiModuleLabel.java @@ -0,0 +1,41 @@ +package org.argeo.cms.spring.osgi; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; + +/** + * Logs the name and version of an OSGi bundle based on its + * {@link BundleContext}. + */ +public class OsgiModuleLabel { + private final static Log log = LogFactory.getLog(OsgiModuleLabel.class); + + private Bundle bundle; + + public OsgiModuleLabel() { + } + + /** Sets without logging. */ + public OsgiModuleLabel(Bundle bundle) { + this.bundle = bundle; + } + + /** + * Retrieved bundle from a bundle context and logs it. Typically to be set + * as a Spring bean. + */ + public void setBundleContext(BundleContext bundleContext) { + this.bundle = bundleContext.getBundle(); + log.info(msg()); + } + + public String msg() { + String name = bundle.getHeaders().get(Constants.BUNDLE_NAME).toString(); + String symbolicName = bundle.getSymbolicName(); + String version = bundle.getVersion().toString(); + return name + " v" + version + " (" + symbolicName + ")"; + } +} diff --git a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/EclipseArgeoMonitor.java b/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/EclipseArgeoMonitor.java deleted file mode 100644 index 46c19b564..000000000 --- a/org.argeo.eclipse.ui/src/org/argeo/eclipse/ui/EclipseArgeoMonitor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * 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.eclipse.ui; - -import org.eclipse.core.runtime.IProgressMonitor; - -/** - * @deprecated use {@link EclipseJcrMonitor} instead - */ -@Deprecated -public class EclipseArgeoMonitor extends EclipseJcrMonitor { - public EclipseArgeoMonitor(IProgressMonitor progressMonitor) { - super(progressMonitor); - } -} diff --git a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java index e7c94609f..b732a98ac 100644 --- a/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java +++ b/org.argeo.enterprise/ext/test/org/argeo/osgi/useradmin/LdifParserTest.java @@ -12,7 +12,7 @@ import javax.naming.ldap.LdapName; import junit.framework.TestCase; -import org.argeo.util.naming.LdifParser; +import org.argeo.naming.LdifParser; public class LdifParserTest extends TestCase implements BasicTestConstants { public void testBasicLdif() throws Exception { diff --git a/org.argeo.enterprise/src/org/argeo/naming/AttributesDictionary.java b/org.argeo.enterprise/src/org/argeo/naming/AttributesDictionary.java new file mode 100644 index 000000000..fe59c1002 --- /dev/null +++ b/org.argeo.enterprise/src/org/argeo/naming/AttributesDictionary.java @@ -0,0 +1,171 @@ +package org.argeo.naming; + +import java.util.Dictionary; +import java.util.Enumeration; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; + +public class AttributesDictionary extends Dictionary { + private final Attributes attributes; + + /** The provided attributes is wrapped, not copied. */ + public AttributesDictionary(Attributes attributes) { + if (attributes == null) + throw new IllegalArgumentException("Attributes cannot be null"); + this.attributes = attributes; + } + + @Override + public int size() { + return attributes.size(); + } + + @Override + public boolean isEmpty() { + return attributes.size() == 0; + } + + @Override + public Enumeration keys() { + NamingEnumeration namingEnumeration = attributes.getIDs(); + return new Enumeration() { + + @Override + public boolean hasMoreElements() { + return namingEnumeration.hasMoreElements(); + } + + @Override + public String nextElement() { + return namingEnumeration.nextElement(); + } + + }; + } + + @Override + public Enumeration elements() { + NamingEnumeration namingEnumeration = attributes.getIDs(); + return new Enumeration() { + + @Override + public boolean hasMoreElements() { + return namingEnumeration.hasMoreElements(); + } + + @Override + public Object nextElement() { + String key = namingEnumeration.nextElement(); + return get(key); + } + + }; + } + + @Override + /** @returns a String or String[] */ + public Object get(Object key) { + try { + if (key == null) + throw new IllegalArgumentException("Key cannot be null"); + Attribute attr = attributes.get(key.toString()); + if (attr == null) + return null; + if (attr.size() == 0) + throw new IllegalStateException("There must be at least one value"); + else if (attr.size() == 1) { + return attr.get().toString(); + } else {// multiple + String[] res = new String[attr.size()]; + for (int i = 0; i < attr.size(); i++) { + Object value = attr.get(); + if (value == null) + throw new RuntimeException("Values cannot be null"); + res[i] = attr.get(i).toString(); + } + return res; + } + } catch (NamingException e) { + throw new RuntimeException("Cannot get value for " + key, e); + } + } + + @Override + public Object put(String key, Object value) { + if (key == null) + throw new IllegalArgumentException("Key cannot be null"); + if (value == null) + throw new IllegalArgumentException("Value cannot be null"); + + Object oldValue = get(key); + Attribute attr = attributes.get(key); + if (attr == null) { + attr = new BasicAttribute(key); + attributes.put(attr); + } + + if (value instanceof String[]) { + String[] values = (String[]) value; + // clean additional values + for (int i = values.length; i < attr.size(); i++) + attr.remove(i); + // set values + for (int i = 0; i < values.length; i++) { + attr.set(i, values[i]); + } + } else { + if (attr.size() > 1) + throw new IllegalArgumentException("Attribute " + key + " is multi-valued"); + if (attr.size() == 1) { + try { + if (!attr.get(0).equals(value)) + attr.set(0, value.toString()); + } catch (NamingException e) { + throw new RuntimeException("Cannot check existing value", e); + } + } else { + attr.add(value.toString()); + } + } + return oldValue; + } + + @Override + public Object remove(Object key) { + if (key == null) + throw new IllegalArgumentException("Key cannot be null"); + Object oldValue = get(key); + if (oldValue == null) + return null; + return attributes.remove(key.toString()); + } + + /** + * Copy the content of an {@link javax.naming.Attributes} to the + * provided {@link Dictionary}. + */ + public static void copy(Attributes attributes, Dictionary dictionary) { + AttributesDictionary ad = new AttributesDictionary(attributes); + Enumeration keys = ad.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + dictionary.put(key, ad.get(key)); + } + } + + /** + * Copy a {@link Dictionary} into an {@link javax.naming.Attributes}. + */ + public static void copy(Dictionary dictionary, Attributes attributes) { + AttributesDictionary ad = new AttributesDictionary(attributes); + Enumeration keys = dictionary.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + ad.put(key, dictionary.get(key)); + } + } +} diff --git a/org.argeo.enterprise/src/org/argeo/naming/LdifParser.java b/org.argeo.enterprise/src/org/argeo/naming/LdifParser.java new file mode 100644 index 000000000..e47d8133e --- /dev/null +++ b/org.argeo.enterprise/src/org/argeo/naming/LdifParser.java @@ -0,0 +1,145 @@ +package org.argeo.naming; + +import static org.argeo.osgi.useradmin.LdifName.dn; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +import javax.naming.InvalidNameException; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.osgi.useradmin.UserDirectoryException; + +/** Basic LDIF parser. */ +public class LdifParser { + private final static Log log = LogFactory.getLog(LdifParser.class); + + protected Attributes addAttributes(SortedMap res, int lineNumber, LdapName currentDn, + Attributes currentAttributes) { + try { + Rdn nameRdn = currentDn.getRdn(currentDn.size() - 1); + Attribute nameAttr = currentAttributes.get(nameRdn.getType()); + if (nameAttr == null) + currentAttributes.put(nameRdn.getType(), nameRdn.getValue()); + else if (!nameAttr.get().equals(nameRdn.getValue())) + throw new UserDirectoryException( + "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn + + " (shortly before line " + lineNumber + " in LDIF file)"); + Attributes previous = res.put(currentDn, currentAttributes); + if (log.isTraceEnabled()) + log.trace("Added " + currentDn); + return previous; + } catch (NamingException e) { + throw new UserDirectoryException("Cannot add " + currentDn, e); + } + } + + public SortedMap read(InputStream in) throws IOException { + SortedMap res = new TreeMap(); + try { + List lines = new ArrayList<>(); + try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) { + String line; + while ((line = br.readLine()) != null) { + lines.add(line); + } + } + if (lines.size() == 0) + return res; + // add an empty new line since the last line is not checked + if (!lines.get(lines.size() - 1).equals("")) + lines.add(""); + + LdapName currentDn = null; + Attributes currentAttributes = null; + StringBuilder currentEntry = new StringBuilder(); + + readLines: for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { + String line = lines.get(lineNumber); + boolean isLastLine = false; + if (lineNumber == lines.size() - 1) + isLastLine = true; + if (line.startsWith(" ")) { + currentEntry.append(line.substring(1)); + if (!isLastLine) + continue readLines; + } + + if (currentEntry.length() != 0 || isLastLine) { + // read previous attribute + StringBuilder attrId = new StringBuilder(8); + boolean isBase64 = false; + readAttrId: for (int i = 0; i < currentEntry.length(); i++) { + char c = currentEntry.charAt(i); + if (c == ':') { + if (i + 1 < currentEntry.length() && currentEntry.charAt(i + 1) == ':') + isBase64 = true; + currentEntry.delete(0, i + (isBase64 ? 2 : 1)); + break readAttrId; + } else { + attrId.append(c); + } + } + + String attributeId = attrId.toString(); + String cleanValueStr = currentEntry.toString().trim(); + Object attributeValue = isBase64 ? Base64.getDecoder().decode(cleanValueStr) : cleanValueStr; + + // manage DN attributes + if (attributeId.equals(dn.name()) || isLastLine) { + if (currentDn != null) { + // + // ADD + // + Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes); + if (previous != null) { + log.warn("There was already an entry with DN " + currentDn + + ", which has been discarded by a subsequent one."); + } + } + + if (attributeId.equals(dn.name())) + try { + currentDn = new LdapName(attributeValue.toString()); + currentAttributes = new BasicAttributes(true); + } catch (InvalidNameException e) { + log.error(attributeValue + " not a valid DN, skipping the entry."); + currentDn = null; + currentAttributes = null; + } + } + + // store attribute + if (currentAttributes != null) { + Attribute attribute = currentAttributes.get(attributeId); + if (attribute == null) { + attribute = new BasicAttribute(attributeId); + currentAttributes.put(attribute); + } + attribute.add(attributeValue); + } + currentEntry = new StringBuilder(); + } + currentEntry.append(line); + } + } finally { + in.close(); + } + return res; + } +} \ No newline at end of file diff --git a/org.argeo.enterprise/src/org/argeo/naming/LdifWriter.java b/org.argeo.enterprise/src/org/argeo/naming/LdifWriter.java new file mode 100644 index 000000000..6bd4809db --- /dev/null +++ b/org.argeo.enterprise/src/org/argeo/naming/LdifWriter.java @@ -0,0 +1,77 @@ +package org.argeo.naming; + +import static org.argeo.osgi.useradmin.LdifName.dn; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Base64; +import java.util.Map; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.argeo.osgi.useradmin.UserDirectoryException; + +/** Basic LDIF writer */ +public class LdifWriter { + private final Writer writer; + + /** Writer must be closed by caller */ + public LdifWriter(Writer writer) { + this.writer = writer; + } + + /** Stream must be closed by caller */ + public LdifWriter(OutputStream out) { + this(new OutputStreamWriter(out)); + } + + public void writeEntry(LdapName name, Attributes attributes) throws IOException { + try { + // check consistency + Rdn nameRdn = name.getRdn(name.size() - 1); + Attribute nameAttr = attributes.get(nameRdn.getType()); + if (!nameAttr.get().equals(nameRdn.getValue())) + throw new UserDirectoryException( + "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + name); + + writer.append(dn.name() + ":").append(name.toString()).append('\n'); + Attribute objectClassAttr = attributes.get("objectClass"); + if (objectClassAttr != null) + writeAttribute(objectClassAttr); + for (NamingEnumeration attrs = attributes.getAll(); attrs.hasMore();) { + Attribute attribute = attrs.next(); + if (attribute.getID().equals(dn.name()) || attribute.getID().equals("objectClass")) + continue;// skip DN attribute + writeAttribute(attribute); + } + writer.append('\n'); + writer.flush(); + } catch (NamingException e) { + throw new UserDirectoryException("Cannot write LDIF", e); + } + } + + public void write(Map entries) throws IOException { + for (LdapName dn : entries.keySet()) + writeEntry(dn, entries.get(dn)); + } + + protected void writeAttribute(Attribute attribute) throws NamingException, IOException { + for (NamingEnumeration attrValues = attribute.getAll(); attrValues.hasMore();) { + Object value = attrValues.next(); + if (value instanceof byte[]) { + String encoded = Base64.getEncoder().encodeToString((byte[]) value); + writer.append(attribute.getID()).append("::").append(encoded).append('\n'); + } else { + writer.append(attribute.getID()).append(':').append(value.toString()).append('\n'); + } + } + } +} diff --git a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUserAdmin.java b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUserAdmin.java index 521ae8bb6..86ef808d4 100644 --- a/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUserAdmin.java +++ b/org.argeo.enterprise/src/org/argeo/osgi/useradmin/LdifUserAdmin.java @@ -22,8 +22,8 @@ import javax.naming.directory.Attributes; import javax.naming.ldap.LdapName; import javax.transaction.TransactionManager; -import org.argeo.util.naming.LdifParser; -import org.argeo.util.naming.LdifWriter; +import org.argeo.naming.LdifParser; +import org.argeo.naming.LdifWriter; import org.osgi.framework.Filter; import org.osgi.service.useradmin.Role; diff --git a/org.argeo.enterprise/src/org/argeo/util/naming/AttributesDictionary.java b/org.argeo.enterprise/src/org/argeo/util/naming/AttributesDictionary.java deleted file mode 100644 index c211e8e8a..000000000 --- a/org.argeo.enterprise/src/org/argeo/util/naming/AttributesDictionary.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.argeo.util.naming; - -import java.util.Dictionary; -import java.util.Enumeration; - -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttribute; - -public class AttributesDictionary extends Dictionary { - private final Attributes attributes; - - /** The provided attributes is wrapped, not copied. */ - public AttributesDictionary(Attributes attributes) { - if (attributes == null) - throw new IllegalArgumentException("Attributes cannot be null"); - this.attributes = attributes; - } - - @Override - public int size() { - return attributes.size(); - } - - @Override - public boolean isEmpty() { - return attributes.size() == 0; - } - - @Override - public Enumeration keys() { - NamingEnumeration namingEnumeration = attributes.getIDs(); - return new Enumeration() { - - @Override - public boolean hasMoreElements() { - return namingEnumeration.hasMoreElements(); - } - - @Override - public String nextElement() { - return namingEnumeration.nextElement(); - } - - }; - } - - @Override - public Enumeration elements() { - NamingEnumeration namingEnumeration = attributes.getIDs(); - return new Enumeration() { - - @Override - public boolean hasMoreElements() { - return namingEnumeration.hasMoreElements(); - } - - @Override - public Object nextElement() { - String key = namingEnumeration.nextElement(); - return get(key); - } - - }; - } - - @Override - /** @returns a String or String[] */ - public Object get(Object key) { - try { - if (key == null) - throw new IllegalArgumentException("Key cannot be null"); - Attribute attr = attributes.get(key.toString()); - if (attr == null) - return null; - if (attr.size() == 0) - throw new IllegalStateException("There must be at least one value"); - else if (attr.size() == 1) { - return attr.get().toString(); - } else {// multiple - String[] res = new String[attr.size()]; - for (int i = 0; i < attr.size(); i++) { - Object value = attr.get(); - if (value == null) - throw new RuntimeException("Values cannot be null"); - res[i] = attr.get(i).toString(); - } - return res; - } - } catch (NamingException e) { - throw new RuntimeException("Cannot get value for " + key, e); - } - } - - @Override - public Object put(String key, Object value) { - if (key == null) - throw new IllegalArgumentException("Key cannot be null"); - if (value == null) - throw new IllegalArgumentException("Value cannot be null"); - - Object oldValue = get(key); - Attribute attr = attributes.get(key); - if (attr == null) { - attr = new BasicAttribute(key); - attributes.put(attr); - } - - if (value instanceof String[]) { - String[] values = (String[]) value; - // clean additional values - for (int i = values.length; i < attr.size(); i++) - attr.remove(i); - // set values - for (int i = 0; i < values.length; i++) { - attr.set(i, values[i]); - } - } else { - if (attr.size() > 1) - throw new IllegalArgumentException("Attribute " + key + " is multi-valued"); - if (attr.size() == 1) { - try { - if (!attr.get(0).equals(value)) - attr.set(0, value.toString()); - } catch (NamingException e) { - throw new RuntimeException("Cannot check existing value", e); - } - } else { - attr.add(value.toString()); - } - } - return oldValue; - } - - @Override - public Object remove(Object key) { - if (key == null) - throw new IllegalArgumentException("Key cannot be null"); - Object oldValue = get(key); - if (oldValue == null) - return null; - return attributes.remove(key.toString()); - } - - /** - * Copy the content of an {@link javax.naming.Attributes} to the - * provided {@link Dictionary}. - */ - public static void copy(Attributes attributes, Dictionary dictionary) { - AttributesDictionary ad = new AttributesDictionary(attributes); - Enumeration keys = ad.keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - dictionary.put(key, ad.get(key)); - } - } - - /** - * Copy a {@link Dictionary} into an {@link javax.naming.Attributes}. - */ - public static void copy(Dictionary dictionary, Attributes attributes) { - AttributesDictionary ad = new AttributesDictionary(attributes); - Enumeration keys = dictionary.keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - ad.put(key, dictionary.get(key)); - } - } -} diff --git a/org.argeo.enterprise/src/org/argeo/util/naming/LdifParser.java b/org.argeo.enterprise/src/org/argeo/util/naming/LdifParser.java deleted file mode 100644 index ec73e8acc..000000000 --- a/org.argeo.enterprise/src/org/argeo/util/naming/LdifParser.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.argeo.util.naming; - -import static org.argeo.osgi.useradmin.LdifName.dn; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.naming.InvalidNameException; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttribute; -import javax.naming.directory.BasicAttributes; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.osgi.useradmin.UserDirectoryException; - -/** Basic LDIF parser. */ -public class LdifParser { - private final static Log log = LogFactory.getLog(LdifParser.class); - - protected Attributes addAttributes(SortedMap res, int lineNumber, LdapName currentDn, - Attributes currentAttributes) { - try { - Rdn nameRdn = currentDn.getRdn(currentDn.size() - 1); - Attribute nameAttr = currentAttributes.get(nameRdn.getType()); - if (nameAttr == null) - currentAttributes.put(nameRdn.getType(), nameRdn.getValue()); - else if (!nameAttr.get().equals(nameRdn.getValue())) - throw new UserDirectoryException( - "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn - + " (shortly before line " + lineNumber + " in LDIF file)"); - Attributes previous = res.put(currentDn, currentAttributes); - if (log.isTraceEnabled()) - log.trace("Added " + currentDn); - return previous; - } catch (NamingException e) { - throw new UserDirectoryException("Cannot add " + currentDn, e); - } - } - - public SortedMap read(InputStream in) throws IOException { - SortedMap res = new TreeMap(); - try { - List lines = new ArrayList<>(); - try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) { - String line; - while ((line = br.readLine()) != null) { - lines.add(line); - } - } - if (lines.size() == 0) - return res; - // add an empty new line since the last line is not checked - if (!lines.get(lines.size() - 1).equals("")) - lines.add(""); - - LdapName currentDn = null; - Attributes currentAttributes = null; - StringBuilder currentEntry = new StringBuilder(); - - readLines: for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { - String line = lines.get(lineNumber); - boolean isLastLine = false; - if (lineNumber == lines.size() - 1) - isLastLine = true; - if (line.startsWith(" ")) { - currentEntry.append(line.substring(1)); - if (!isLastLine) - continue readLines; - } - - if (currentEntry.length() != 0 || isLastLine) { - // read previous attribute - StringBuilder attrId = new StringBuilder(8); - boolean isBase64 = false; - readAttrId: for (int i = 0; i < currentEntry.length(); i++) { - char c = currentEntry.charAt(i); - if (c == ':') { - if (i + 1 < currentEntry.length() && currentEntry.charAt(i + 1) == ':') - isBase64 = true; - currentEntry.delete(0, i + (isBase64 ? 2 : 1)); - break readAttrId; - } else { - attrId.append(c); - } - } - - String attributeId = attrId.toString(); - String cleanValueStr = currentEntry.toString().trim(); - Object attributeValue = isBase64 ? Base64.getDecoder().decode(cleanValueStr) : cleanValueStr; - - // manage DN attributes - if (attributeId.equals(dn.name()) || isLastLine) { - if (currentDn != null) { - // - // ADD - // - Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes); - if (previous != null) { - log.warn("There was already an entry with DN " + currentDn - + ", which has been discarded by a subsequent one."); - } - } - - if (attributeId.equals(dn.name())) - try { - currentDn = new LdapName(attributeValue.toString()); - currentAttributes = new BasicAttributes(true); - } catch (InvalidNameException e) { - log.error(attributeValue + " not a valid DN, skipping the entry."); - currentDn = null; - currentAttributes = null; - } - } - - // store attribute - if (currentAttributes != null) { - Attribute attribute = currentAttributes.get(attributeId); - if (attribute == null) { - attribute = new BasicAttribute(attributeId); - currentAttributes.put(attribute); - } - attribute.add(attributeValue); - } - currentEntry = new StringBuilder(); - } - currentEntry.append(line); - } - } finally { - in.close(); - } - return res; - } -} \ No newline at end of file diff --git a/org.argeo.enterprise/src/org/argeo/util/naming/LdifWriter.java b/org.argeo.enterprise/src/org/argeo/util/naming/LdifWriter.java deleted file mode 100644 index 37d90b4e4..000000000 --- a/org.argeo.enterprise/src/org/argeo/util/naming/LdifWriter.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.argeo.util.naming; - -import static org.argeo.osgi.useradmin.LdifName.dn; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Base64; -import java.util.Map; - -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.argeo.osgi.useradmin.UserDirectoryException; - -/** Basic LDIF writer */ -public class LdifWriter { - private final Writer writer; - - /** Writer must be closed by caller */ - public LdifWriter(Writer writer) { - this.writer = writer; - } - - /** Stream must be closed by caller */ - public LdifWriter(OutputStream out) { - this(new OutputStreamWriter(out)); - } - - public void writeEntry(LdapName name, Attributes attributes) throws IOException { - try { - // check consistency - Rdn nameRdn = name.getRdn(name.size() - 1); - Attribute nameAttr = attributes.get(nameRdn.getType()); - if (!nameAttr.get().equals(nameRdn.getValue())) - throw new UserDirectoryException( - "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + name); - - writer.append(dn.name() + ":").append(name.toString()).append('\n'); - Attribute objectClassAttr = attributes.get("objectClass"); - if (objectClassAttr != null) - writeAttribute(objectClassAttr); - for (NamingEnumeration attrs = attributes.getAll(); attrs.hasMore();) { - Attribute attribute = attrs.next(); - if (attribute.getID().equals(dn.name()) || attribute.getID().equals("objectClass")) - continue;// skip DN attribute - writeAttribute(attribute); - } - writer.append('\n'); - writer.flush(); - } catch (NamingException e) { - throw new UserDirectoryException("Cannot write LDIF", e); - } - } - - public void write(Map entries) throws IOException { - for (LdapName dn : entries.keySet()) - writeEntry(dn, entries.get(dn)); - } - - protected void writeAttribute(Attribute attribute) throws NamingException, IOException { - for (NamingEnumeration attrValues = attribute.getAll(); attrValues.hasMore();) { - Object value = attrValues.next(); - if (value instanceof byte[]) { - String encoded = Base64.getEncoder().encodeToString((byte[]) value); - writer.append(attribute.getID()).append("::").append(encoded).append('\n'); - } else { - writer.append(attribute.getID()).append(':').append(value.toString()).append('\n'); - } - } - } -} diff --git a/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java b/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java deleted file mode 100644 index 52a9883ee..000000000 --- a/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/OpenInViewSessionProvider.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * 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.jackrabbit.servlet; - -import java.io.Serializable; - -import javax.jcr.LoginException; -import javax.jcr.Repository; -import javax.jcr.RepositoryException; -import javax.jcr.Session; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.jackrabbit.server.SessionProvider; -import org.argeo.jcr.JcrUtils; - -/** - * Implements an open session in view patter: a new JCR session is created for - * each request - */ -@Deprecated -public class OpenInViewSessionProvider implements SessionProvider, Serializable { - private static final long serialVersionUID = 2270957712453841368L; - - private final static Log log = LogFactory - .getLog(OpenInViewSessionProvider.class); - - public Session getSession(HttpServletRequest request, Repository rep, - String workspace) throws LoginException, ServletException, - RepositoryException { - return login(request, rep, workspace); - } - - protected Session login(HttpServletRequest request, Repository repository, - String workspace) throws RepositoryException { - if (log.isTraceEnabled()) - log.trace("Login to workspace " - + (workspace == null ? "" : workspace) - + " in web session " + request.getSession().getId()); - return repository.login(workspace); - } - - public void releaseSession(Session session) { - JcrUtils.logoutQuietly(session); - if (log.isTraceEnabled()) - log.trace("Logged out remote JCR session " + session); - } - - public void init() { - } - - public void destroy() { - } - -} diff --git a/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/RemotingServlet.java b/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/RemotingServlet.java deleted file mode 100644 index 3fdb5d2e1..000000000 --- a/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/RemotingServlet.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * 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.jackrabbit.servlet; - -import javax.jcr.Repository; - -import org.apache.jackrabbit.server.SessionProvider; -import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet; - -/** Provides remote access to a JCR repository */ -@Deprecated -public class RemotingServlet extends JcrRemotingServlet { - public final static String INIT_PARAM_RESOURCE_PATH_PREFIX = JcrRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX; - public final static String INIT_PARAM_HOME = JcrRemotingServlet.INIT_PARAM_HOME; - public final static String INIT_PARAM_TMP_DIRECTORY = JcrRemotingServlet.INIT_PARAM_TMP_DIRECTORY; - public final static String INIT_PARAM_PROTECTED_HANDLERS_CONFIG = JcrRemotingServlet.INIT_PARAM_PROTECTED_HANDLERS_CONFIG; - - private static final long serialVersionUID = 3131835511468341309L; - - private final Repository repository; - private final SessionProvider sessionProvider; - - public RemotingServlet(Repository repository, - SessionProvider sessionProvider) { - this.repository = repository; - this.sessionProvider = sessionProvider; - } - - @Override - protected Repository getRepository() { - return repository; - } - - @Override - protected SessionProvider getSessionProvider() { - return sessionProvider; - } - -} diff --git a/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/WebdavServlet.java b/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/WebdavServlet.java deleted file mode 100644 index e3176b742..000000000 --- a/org.argeo.jcr/src/org/argeo/jackrabbit/servlet/WebdavServlet.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * 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.jackrabbit.servlet; - -import java.io.IOException; - -import javax.jcr.Repository; -import javax.servlet.ServletException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.jackrabbit.server.SessionProvider; -import org.apache.jackrabbit.webdav.DavException; -import org.apache.jackrabbit.webdav.DavResource; -import org.apache.jackrabbit.webdav.WebdavRequest; -import org.apache.jackrabbit.webdav.WebdavResponse; -import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet; - -/** WebDav servlet whose repository is injected */ -@Deprecated -public class WebdavServlet extends SimpleWebdavServlet { - public final static String INIT_PARAM_RESOURCE_CONFIG = SimpleWebdavServlet.INIT_PARAM_RESOURCE_CONFIG; - public final static String INIT_PARAM_RESOURCE_PATH_PREFIX = SimpleWebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX; - - private static final long serialVersionUID = -369787931175177080L; - - private final static Log log = LogFactory.getLog(WebdavServlet.class); - - private final Repository repository; - - public WebdavServlet(Repository repository, SessionProvider sessionProvider) { - this.repository = repository; - setSessionProvider(sessionProvider); - } - - public Repository getRepository() { - return repository; - } - - @Override - protected boolean execute(WebdavRequest request, WebdavResponse response, - int method, DavResource resource) throws ServletException, - IOException, DavException { - if (log.isTraceEnabled()) - log.trace(request.getMethod() + "\t" + request.getPathInfo()); - boolean res = super.execute(request, response, method, resource); - return res; - } - -} diff --git a/org.argeo.jcr/src/org/argeo/jcr/JcrAuthorizations.java b/org.argeo.jcr/src/org/argeo/jcr/JcrAuthorizations.java new file mode 100644 index 000000000..22592fa17 --- /dev/null +++ b/org.argeo.jcr/src/org/argeo/jcr/JcrAuthorizations.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2007-2012 Argeo GmbH + * + * 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.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.AccessControlManager; +import javax.jcr.security.Privilege; + +/** Apply authorizations to a JCR repository. */ +public class JcrAuthorizations implements Runnable { + // private final static Log log = + // LogFactory.getLog(JcrAuthorizations.class); + + private Repository repository; + private String workspace = null; + + private String securityWorkspace = "security"; + + /** + * key := privilege1,privilege2/path/to/node
+ * value := group1,group2,user1 + */ + private Map principalPrivileges = new HashMap(); + + public void run() { + String currentWorkspace = workspace; + Session session = null; + try { + if (workspace != null && workspace.equals("*")) { + session = repository.login(); + String[] workspaces = session.getWorkspace() + .getAccessibleWorkspaceNames(); + JcrUtils.logoutQuietly(session); + for (String wksp : workspaces) { + currentWorkspace = wksp; + if (currentWorkspace.equals(securityWorkspace)) + continue; + session = repository.login(currentWorkspace); + initAuthorizations(session); + JcrUtils.logoutQuietly(session); + } + } else { + session = repository.login(workspace); + initAuthorizations(session); + } + } catch (Exception e) { + JcrUtils.discardQuietly(session); + throw new ArgeoJcrException( + "Cannot set authorizations " + principalPrivileges + + " on workspace " + currentWorkspace, e); + } finally { + JcrUtils.logoutQuietly(session); + } + } + + protected void processWorkspace(String workspace) { + Session session = null; + try { + session = repository.login(workspace); + initAuthorizations(session); + } catch (Exception e) { + JcrUtils.discardQuietly(session); + throw new ArgeoJcrException("Cannot set authorizations " + + principalPrivileges + " on repository " + repository, e); + } 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 ArgeoJcrException("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 privs = new ArrayList(); + 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); + JcrUtils.addPrivileges(session, path, principal, privs); + // if (log.isDebugEnabled()) { + // StringBuffer privBuf = new StringBuffer(); + // for (Privilege priv : privs) + // privBuf.append(priv.getName()); + // log.debug("Added privileges " + privBuf + " to " + // + principal.getName() + " on " + path + " in '" + // + session.getWorkspace().getName() + "'"); + // } + } + } + + // if (log.isDebugEnabled()) + // log.debug("JCR authorizations applied on '" + // + session.getWorkspace().getName() + "'"); + } + + /** + * 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 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); + // session.save(); + // if (log.isDebugEnabled()) { + // StringBuffer buf = new StringBuffer(""); + // for (int i = 0; i < privs.size(); i++) { + // if (i != 0) + // buf.append(','); + // buf.append(privs.get(i).getName()); + // } + // log.debug("Added privilege(s) '" + buf + "' to '" + // + principal.getName() + "' on " + path + // + " from workspace '" + // + session.getWorkspace().getName() + "'"); + // } + // } else { + // throw new ArgeoJcrException("Don't know how to apply privileges " + // + privs + " to " + principal + " on " + path + // + " from workspace '" + session.getWorkspace().getName() + // + "'"); + // } + // } + + @Deprecated + public void setGroupPrivileges(Map groupPrivileges) { + this.principalPrivileges = groupPrivileges; + } + + public void setPrincipalPrivileges(Map principalPrivileges) { + this.principalPrivileges = principalPrivileges; + } + + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setWorkspace(String workspace) { + this.workspace = workspace; + } + + public void setSecurityWorkspace(String securityWorkspace) { + this.securityWorkspace = securityWorkspace; + } + +} diff --git a/org.argeo.jcr/src/org/argeo/jcr/security/JcrAuthorizations.java b/org.argeo.jcr/src/org/argeo/jcr/security/JcrAuthorizations.java deleted file mode 100644 index 3e8e3a2ff..000000000 --- a/org.argeo.jcr/src/org/argeo/jcr/security/JcrAuthorizations.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (C) 2007-2012 Argeo GmbH - * - * 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.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.AccessControlManager; -import javax.jcr.security.Privilege; - -import org.argeo.jcr.ArgeoJcrException; -import org.argeo.jcr.JcrUtils; -import org.argeo.jcr.SimplePrincipal; - -/** Apply authorizations to a JCR repository. */ -public class JcrAuthorizations implements Runnable { - // private final static Log log = - // LogFactory.getLog(JcrAuthorizations.class); - - private Repository repository; - private String workspace = null; - - private String securityWorkspace = "security"; - - /** - * key := privilege1,privilege2/path/to/node
- * value := group1,group2,user1 - */ - private Map principalPrivileges = new HashMap(); - - public void run() { - String currentWorkspace = workspace; - Session session = null; - try { - if (workspace != null && workspace.equals("*")) { - session = repository.login(); - String[] workspaces = session.getWorkspace() - .getAccessibleWorkspaceNames(); - JcrUtils.logoutQuietly(session); - for (String wksp : workspaces) { - currentWorkspace = wksp; - if (currentWorkspace.equals(securityWorkspace)) - continue; - session = repository.login(currentWorkspace); - initAuthorizations(session); - JcrUtils.logoutQuietly(session); - } - } else { - session = repository.login(workspace); - initAuthorizations(session); - } - } catch (Exception e) { - JcrUtils.discardQuietly(session); - throw new ArgeoJcrException( - "Cannot set authorizations " + principalPrivileges - + " on workspace " + currentWorkspace, e); - } finally { - JcrUtils.logoutQuietly(session); - } - } - - protected void processWorkspace(String workspace) { - Session session = null; - try { - session = repository.login(workspace); - initAuthorizations(session); - } catch (Exception e) { - JcrUtils.discardQuietly(session); - throw new ArgeoJcrException("Cannot set authorizations " - + principalPrivileges + " on repository " + repository, e); - } 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 ArgeoJcrException("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 privs = new ArrayList(); - 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); - JcrUtils.addPrivileges(session, path, principal, privs); - // if (log.isDebugEnabled()) { - // StringBuffer privBuf = new StringBuffer(); - // for (Privilege priv : privs) - // privBuf.append(priv.getName()); - // log.debug("Added privileges " + privBuf + " to " - // + principal.getName() + " on " + path + " in '" - // + session.getWorkspace().getName() + "'"); - // } - } - } - - // if (log.isDebugEnabled()) - // log.debug("JCR authorizations applied on '" - // + session.getWorkspace().getName() + "'"); - } - - /** - * 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 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); - // session.save(); - // if (log.isDebugEnabled()) { - // StringBuffer buf = new StringBuffer(""); - // for (int i = 0; i < privs.size(); i++) { - // if (i != 0) - // buf.append(','); - // buf.append(privs.get(i).getName()); - // } - // log.debug("Added privilege(s) '" + buf + "' to '" - // + principal.getName() + "' on " + path - // + " from workspace '" - // + session.getWorkspace().getName() + "'"); - // } - // } else { - // throw new ArgeoJcrException("Don't know how to apply privileges " - // + privs + " to " + principal + " on " + path - // + " from workspace '" + session.getWorkspace().getName() - // + "'"); - // } - // } - - @Deprecated - public void setGroupPrivileges(Map groupPrivileges) { - this.principalPrivileges = groupPrivileges; - } - - public void setPrincipalPrivileges(Map principalPrivileges) { - this.principalPrivileges = principalPrivileges; - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - - public void setWorkspace(String workspace) { - this.workspace = workspace; - } - - public void setSecurityWorkspace(String securityWorkspace) { - this.securityWorkspace = securityWorkspace; - } - -}