Introduce Spring support in SLC Eclipse 4.
authorMathieu Baudier <mbaudier@argeo.org>
Fri, 20 Mar 2020 07:52:22 +0000 (08:52 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Fri, 20 Mar 2020 07:52:22 +0000 (08:52 +0100)
dep/org.argeo.slc.dep.spring.e4.rap/.gitignore [new file with mode: 0644]
dep/org.argeo.slc.dep.spring.e4.rap/META-INF/.gitignore [new file with mode: 0644]
dep/org.argeo.slc.dep.spring.e4.rap/bnd.bnd [new file with mode: 0644]
dep/org.argeo.slc.dep.spring.e4.rap/pom.xml [new file with mode: 0644]
dep/pom.xml
org.argeo.slc.spring/src/org/argeo/slc/spring/auth/AbstractSystemExecution.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/spring/auth/AuthenticatedApplicationContextInitialization.java [new file with mode: 0644]
org.argeo.slc.spring/src/org/argeo/slc/spring/auth/SimpleRoleRegistration.java [new file with mode: 0644]

diff --git a/dep/org.argeo.slc.dep.spring.e4.rap/.gitignore b/dep/org.argeo.slc.dep.spring.e4.rap/.gitignore
new file mode 100644 (file)
index 0000000..5931da6
--- /dev/null
@@ -0,0 +1,2 @@
+/target/
+*.target
diff --git a/dep/org.argeo.slc.dep.spring.e4.rap/META-INF/.gitignore b/dep/org.argeo.slc.dep.spring.e4.rap/META-INF/.gitignore
new file mode 100644 (file)
index 0000000..4854a41
--- /dev/null
@@ -0,0 +1 @@
+/MANIFEST.MF
diff --git a/dep/org.argeo.slc.dep.spring.e4.rap/bnd.bnd b/dep/org.argeo.slc.dep.spring.e4.rap/bnd.bnd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dep/org.argeo.slc.dep.spring.e4.rap/pom.xml b/dep/org.argeo.slc.dep.spring.e4.rap/pom.xml
new file mode 100644 (file)
index 0000000..40a3c32
--- /dev/null
@@ -0,0 +1,139 @@
+<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.argeo.slc</groupId>
+               <artifactId>dep</artifactId>
+               <version>2.1.17-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.slc.dep.spring.e4.rap</artifactId>
+       <name>SLC Spring E4 RAP</name>
+       <dependencies>
+               <!-- Parent dependencies -->
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.dep.cms.sdk</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <type>pom</type>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.slc</groupId>
+                       <artifactId>org.argeo.slc.dep.spring</artifactId>
+                       <version>2.1.17-SNAPSHOT</version>
+                       <type>pom</type>
+               </dependency>
+
+
+               <dependency>
+                       <groupId>org.argeo.slc</groupId>
+                       <artifactId>org.argeo.slc.e4</artifactId>
+                       <version>2.1.17-SNAPSHOT</version>
+               </dependency>
+
+               <!-- OSGi Boot for platform generation only, as it could be used by regular 
+                       Java applications to launch an OSGi runtime. -->
+               <dependency>
+                       <groupId>org.argeo.commons</groupId>
+                       <artifactId>org.argeo.osgi.boot</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
+               </dependency>
+
+               <!-- ALM Third Parties -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp.apache.ant</groupId> -->
+               <!-- <artifactId>org.apache.ant</artifactId> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp.apache.ant</groupId> -->
+               <!-- <artifactId>org.apache.ant.launch</artifactId> -->
+               <!-- </dependency> -->
+
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp.sdk</groupId> -->
+               <!-- <artifactId>biz.aQute.bndlib</artifactId> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp.sdk</groupId> -->
+               <!-- <artifactId>org.junit</artifactId> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp.sdk</groupId> -->
+               <!-- <artifactId>org.redline-rpm</artifactId> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp.misc</groupId> -->
+               <!-- <artifactId>com.googlecode.javaewah.JavaEWAH</artifactId> -->
+               <!-- </dependency> -->
+               <!-- <dependency> -->
+               <!-- <groupId>org.argeo.tp.misc</groupId> -->
+               <!-- <artifactId>org.eclipse.jgit</artifactId> -->
+               <!-- </dependency> -->
+       </dependencies>
+       <profiles>
+               <profile>
+                       <id>rpmbuild</id>
+                       <build>
+                               <plugins>
+                                       <plugin>
+                                               <artifactId>maven-assembly-plugin</artifactId>
+                                               <executions>
+                                                       <execution>
+                                                               <id>prepare-source</id>
+                                                               <phase>package</phase>
+                                                               <goals>
+                                                                       <goal>single</goal>
+                                                               </goals>
+                                                               <configuration>
+                                                                       <descriptorRefs>
+                                                                               <descriptorRef>a2-source</descriptorRef>
+                                                                       </descriptorRefs>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                       </plugin>
+                                       <plugin>
+                                               <groupId>org.codehaus.mojo</groupId>
+                                               <artifactId>rpm-maven-plugin</artifactId>
+                                               <executions>
+                                                       <execution>
+                                                               <id>rpm-argeo</id>
+                                                               <phase>package</phase>
+                                                               <goals>
+                                                                       <goal>rpm</goal>
+                                                               </goals>
+                                                               <configuration>
+                                                                       <name>slc-e4-rap</name>
+                                                                       <mappings>
+                                                                               <mapping>
+                                                                                       <directory>/usr/share/osgi</directory>
+                                                                                       <username>root</username>
+                                                                                       <groupname>root</groupname>
+                                                                                       <filemode>644</filemode>
+                                                                                       <directoryIncluded>true</directoryIncluded>
+                                                                                       <sources>
+                                                                                               <source>
+                                                                                                       <location>${project.build.directory}/${project.artifactId}-${project.version}-a2-source</location>
+                                                                                                       <includes>
+                                                                                                               <include>**/*.jar</include>
+                                                                                                       </includes>
+                                                                                               </source>
+                                                                                       </sources>
+                                                                               </mapping>
+                                                                       </mappings>
+                                                                       <requires>
+                                                                               <require>argeo-cms-e4-rap</require>
+                                                                               <require>argeo-cms-sdk-tp</require>
+                                                                               <require>slc-agent</require>
+                                                                       </requires>
+                                                               </configuration>
+                                                       </execution>
+                                               </executions>
+                                       </plugin>
+                               </plugins>
+                       </build>
+               </profile>
+       </profiles>
+</project>
\ No newline at end of file
index 6a5d92084a1a5e49538ba8d0cc28b717c7c0808a..e89b4b200339242269f31786bc5491ef87b96ac4 100644 (file)
@@ -13,6 +13,7 @@
                <module>org.argeo.slc.dep.minimal</module>
                <module>org.argeo.slc.dep.spring</module>
                <module>org.argeo.slc.dep.e4.rap</module>
+               <module>org.argeo.slc.dep.spring.e4.rap</module>
                <!--  Legacy -->
                <module>org.argeo.slc.dep.backend</module>
        </modules>
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/spring/auth/AbstractSystemExecution.java b/org.argeo.slc.spring/src/org/argeo/slc/spring/auth/AbstractSystemExecution.java
new file mode 100644 (file)
index 0000000..ba358fa
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.slc.spring.auth;
+
+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.api.NodeConstants;
+import org.argeo.slc.SlcException;
+
+/** 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();
+
+       /** Authenticate the calling thread */
+       protected void authenticateAsSystem() {
+               ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
+               Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+               try {
+                       LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject);
+                       lc.login();
+               } catch (LoginException e) {
+                       throw new SlcException("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(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN, subject);
+                       lc.logout();
+               } catch (LoginException e) {
+                       throw new SlcException("Cannot logout as system", e);
+               } finally {
+                       Thread.currentThread().setContextClassLoader(origClassLoader);
+               }
+       }
+
+       protected Subject getSubject() {
+               return subject;
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/spring/auth/AuthenticatedApplicationContextInitialization.java b/org.argeo.slc.spring/src/org/argeo/slc/spring/auth/AuthenticatedApplicationContextInitialization.java
new file mode 100644 (file)
index 0000000..5702134
--- /dev/null
@@ -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.slc.spring.auth;
+
+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<String> beanNames = new ArrayList<String>();
+
+       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<String> 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<Void>() {
+                               @Override
+                               public Void run() {
+                                       SecurityContextProvider scp = new SimpleSecurityContextProvider(
+                                                       AccessController.getContext());
+                                       beanFactory.setSecurityContextProvider(scp);
+                                       return null;
+                               }
+                       });
+               }
+       }
+}
diff --git a/org.argeo.slc.spring/src/org/argeo/slc/spring/auth/SimpleRoleRegistration.java b/org.argeo.slc.spring/src/org/argeo/slc/spring/auth/SimpleRoleRegistration.java
new file mode 100644 (file)
index 0000000..44b7b79
--- /dev/null
@@ -0,0 +1,89 @@
+package org.argeo.slc.spring.auth;
+
+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.slc.SlcException;
+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<String> roles = new ArrayList<String>();
+       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 SlcException("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 SlcException("Badly formatted role name " + name, e);
+               }
+       }
+
+       public void setRole(String role) {
+               this.role = role;
+       }
+
+       public void setRoles(List<String> roles) {
+               this.roles = roles;
+       }
+
+       public void setUserAdmin(UserAdmin userAdminService) {
+               this.userAdmin = userAdminService;
+       }
+
+       public void setUserTransaction(UserTransaction userTransaction) {
+               this.userTransaction = userTransaction;
+       }
+
+}