Improve packaging (esp. security)
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 16 Feb 2011 13:55:52 +0000 (13:55 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 16 Feb 2011 13:55:52 +0000 (13:55 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@4149 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

62 files changed:
eclipse/features/org.argeo.eclipse.dep.common/pom.xml
eclipse/features/org.argeo.eclipse.dep.rap/pom.xml
eclipse/features/org.argeo.eclipse.dep.rcp/pom.xml
eclipse/plugins/org.argeo.eclipse.ui/pom.xml
pom.xml
security/eclipse/plugins/org.argeo.security.equinox/.classpath
security/eclipse/plugins/org.argeo.security.equinox/build.properties
security/eclipse/plugins/org.argeo.security.equinox/pom.xml
security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/CurrentUser.java [deleted file]
security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/EquinoxSecurity.java [deleted file]
security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/SpringLoginModule.java
security/eclipse/plugins/org.argeo.security.equinox/src/main/resources/org/argeo/security/equinox/jaas_default.txt [deleted file]
security/eclipse/plugins/org.argeo.security.ui.application/META-INF/jaas_default.txt [new file with mode: 0644]
security/eclipse/plugins/org.argeo.security.ui.application/SecureRCP.product
security/eclipse/plugins/org.argeo.security.ui.application/pom.xml
security/eclipse/plugins/org.argeo.security.ui.application/src/main/java/org/argeo/security/ui/application/AbstractSecureApplication.java
security/eclipse/plugins/org.argeo.security.ui.application/src/main/java/org/argeo/security/ui/application/SecureApplicationActivator.java [new file with mode: 0644]
security/eclipse/plugins/org.argeo.security.ui.rap/pom.xml
security/eclipse/plugins/org.argeo.security.ui/pom.xml
security/eclipse/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/CurrentUser.java [new file with mode: 0644]
security/eclipse/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/SecurityPerspective.java
security/eclipse/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/views/CurrentUserView.java
security/eclipse/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/views/UsersView.java
security/eclipse/plugins/pom.xml
security/runtime/org.argeo.security.activemq/.classpath [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/.project [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/build.properties [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/pom.xml [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/ActiveMqSecurityBrokerPlugin.java [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/ActiveMqSpringSecurityContext.java [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/SecuredActiveMqConnectionFactory.java [new file with mode: 0644]
security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/UserPasswordDialog.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/build.properties
security/runtime/org.argeo.security.core/pom.xml
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/ActiveMqSecurityBrokerPlugin.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/ActiveMqSpringSecurityContext.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/SecuredActiveMqConnectionFactory.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/UserPasswordDialog.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoUserDetailsContextMapper.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/UserNatureMapper.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/nature/CoworkerUserNatureMapper.java [deleted file]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/nature/SimpleUserNatureMapper.java [deleted file]
security/runtime/org.argeo.security.ldap/.classpath [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/.project [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/build.properties [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/pom.xml [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoUserDetailsContextMapper.java [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/UserNatureMapper.java [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/nature/CoworkerUserNatureMapper.java [new file with mode: 0644]
security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/nature/SimpleUserNatureMapper.java [new file with mode: 0644]
security/runtime/pom.xml
server/dep/org.argeo.server.dep.jackrabbit.server/pom.xml
server/dep/org.argeo.server.dep.tomcat/pom.xml
server/runtime/org.argeo.server.core/pom.xml
server/runtime/org.argeo.server.jackrabbit/pom.xml
server/runtime/org.argeo.server.jackrabbit/src/main/java/org/argeo/server/jackrabbit/JackrabbitContainer.java

index 8562cf092f47c47b6f6de0514cc484ff468b4ddb..3bc6845e1036071ff977682ccbc58bffc62a9bff 100644 (file)
@@ -8,7 +8,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.eclipse.dep.common</artifactId>
-       <name>Argeo Commons RCP Dependencies</name>
+       <name>Commons Eclipse Dependencies</name>
        <build>
                <plugins>
                        <plugin>
index b586a8011d17c01385f4646fd83b044898c01374..bbbd724078cf35f5a372a57e8e1d644af880493c 100644 (file)
@@ -8,7 +8,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.eclipse.dep.rap</artifactId>
-       <name>Argeo Commons RAP Dependencies</name>
+       <name>Commons RAP Dependencies</name>
        <build>
                <plugins>
                        <plugin>
index dbcc14f9339f4c73713f6225f8d61c1e9dbf6177..69c731326bbd33ae895bafb219e51287374f49d7 100644 (file)
@@ -8,7 +8,7 @@
                <relativePath>..</relativePath>
        </parent>
        <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
-       <name>Argeo Commons RCP Dependencies</name>
+       <name>Commons RCP Dependencies</name>
        <build>
                <plugins>
                        <plugin>
index acbba4ea4e07891298551ee9bcec661d53dc0542..6192d795cfcbd370a044eb6a2f027edc53a796be 100644 (file)
@@ -31,7 +31,7 @@
                                        <instructions>
                                                <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
                                                <Bundle-Activator>org.argeo.eclipse.ui.ArgeoUiPlugin</Bundle-Activator>
-                                               <Require-Bundle>org.eclipse.ui;resolution:=optional,org.eclipse.rap.ui;resolution:=optional,org.eclipse.core.runtime,org.springframework.osgi.extender</Require-Bundle>
+                                               <Require-Bundle>org.eclipse.ui;resolution:=optional,org.eclipse.rap.ui;resolution:=optional,org.eclipse.core.runtime</Require-Bundle>
                                                <Import-Package>
                                                        org.springframework.beans.factory,
                                                        org.springframework.core.io.support,
diff --git a/pom.xml b/pom.xml
index b928bd34e06632631032a16a204f45000e1cb5b6..f67dfdf4cf92c89e359a78e73f5299d02190c729 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@
                <version.argeo-commons>0.2.3-SNAPSHOT</version.argeo-commons>
                <version.argeo-ria>0.12.5</version.argeo-ria>
                <version.equinox>3.6.1</version.equinox>
-               <version.maven-argeo-osgi>0.1.30</version.maven-argeo-osgi>
+               <version.maven-argeo-osgi>0.1.31-SNAPSHOT</version.maven-argeo-osgi>
                <version.maven-bundle-plugin>2.2.0</version.maven-bundle-plugin>
                <version.maven-argeo-qooxdoo>1.1.1</version.maven-argeo-qooxdoo>
                <site.repoBase>file:///srv/projects/www/commons/site</site.repoBase>
@@ -73,8 +73,8 @@ limitations under the License.
                <module>basic</module>
                <module>osgi</module>
                <module>server</module>
-               <module>security</module>
                <module>eclipse</module>
+               <module>security</module>
                <module>sandbox</module>
        </modules>
        <build>
index d3d5c80958677f1f8de5b580c289b3baf7c5452c..92f19d2ff95b83a87f5210157582c70bb070ed48 100644 (file)
@@ -3,6 +3,5 @@
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
        <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
        <classpathentry kind="src" path="src/main/java"/>
-       <classpathentry kind="src" path="src/main/resources"/>
        <classpathentry kind="output" path="target/classes"/>
 </classpath>
index 5e565ebc8ae2ae2677e24bd0e36657929d269ef5..3e2615fae0c0d9a92f0b29d6c2e462bf0f376d00 100644 (file)
@@ -1,5 +1,4 @@
 bin.includes = META-INF/,\
                plugin.xml
-source.. = src/main/java/,\
-           src/main/resources/
+source.. = src/main/java/
 output.. = target/classes/
index 9f662d802333b697bebf72f5757a9c95b32ab1ac..944a6e0df42bb362fc4443ed145e26175a2ca7cb 100644 (file)
                                <artifactId>maven-bundle-plugin</artifactId>
                                <version>${version.maven-bundle-plugin}</version>
                                <configuration>
+<!--                                   <instructions>-->
+<!--                                           <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>-->
+<!--                                           <Bundle-Activator>org.argeo.security.equinox.EquinoxSecurity</Bundle-Activator>-->
+<!--                                           <Import-Package>-->
+<!--                                                   org.osgi.framework;version="0.0.0",-->
+<!--                                                   !org.eclipse.equinox.security.auth,-->
+<!--                                                   org.springframework.core,-->
+<!--                                                   org.argeo.eclipse.spring,-->
+<!--                                                   *-->
+<!--                                           </Import-Package>-->
+<!--                                           <Require-Bundle>org.eclipse.equinox.security</Require-Bundle>-->
+<!--                                   </instructions>-->
                                        <instructions>
-                                               <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
-                                               <Bundle-Activator>org.argeo.security.equinox.EquinoxSecurity</Bundle-Activator>
                                                <Import-Package>*,
                                                        org.springframework.core,
                                                        org.argeo.eclipse.spring
                        <groupId>org.springframework.security</groupId>
                        <artifactId>org.springframework.security.core</artifactId>
                </dependency>
-
-               <!-- Others -->
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
-               </dependency>
-
        </dependencies>
 </project>
diff --git a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/CurrentUser.java b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/CurrentUser.java
deleted file mode 100644 (file)
index 12cda53..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.argeo.security.equinox;
-
-import java.security.AccessController;
-import java.security.Principal;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-import javax.security.auth.login.LoginException;
-
-import org.argeo.ArgeoException;
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.springframework.security.Authentication;
-import org.springframework.security.GrantedAuthority;
-
-public class CurrentUser {
-       public final static String getUsername() {
-               Subject subject = getSubject();
-               if (subject == null)
-                       return null;
-               Principal principal = subject.getPrincipals().iterator().next();
-               return principal.getName();
-
-       }
-
-       public final static Set<String> roles() {
-               Principal principal = getSubject().getPrincipals().iterator().next();
-               Authentication authentication = (Authentication) principal;
-               Set<String> roles = Collections.synchronizedSet(new HashSet<String>());
-               for (GrantedAuthority ga : authentication.getAuthorities()) {
-                       roles.add(ga.getAuthority());
-               }
-               return Collections.unmodifiableSet(roles);
-       }
-
-       private final static ILoginContext getLoginContext() {
-               return EquinoxSecurity.getLoginContext();
-               // return LoginContextFactory
-               // .createContext(EquinoxSecurity.CONTEXT_SPRING);
-       }
-
-       // private static void login() {
-       // try {
-       // getLoginContext().login();
-       // } catch (LoginException e) {
-       // throw new RuntimeException("Cannot login", e);
-       // }
-       // }
-
-       public final static Subject getSubject() {
-
-               Subject subject = Subject.getSubject(AccessController.getContext());
-               // subject = Subject.getSubject(AccessController.getContext());
-               if (subject == null)
-                       try {
-                               getLoginContext().login();
-                               subject = getLoginContext().getSubject();
-                       } catch (Exception e) {
-                               throw new ArgeoException("Cannot retrieve subject", e);
-                       }
-
-               return subject;
-
-       }
-
-       public static void logout() {
-               try {
-                       getLoginContext().logout();
-               } catch (LoginException e) {
-                       throw new ArgeoException("Cannot log out", e);
-               }
-       }
-}
diff --git a/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/EquinoxSecurity.java b/security/eclipse/plugins/org.argeo.security.equinox/src/main/java/org/argeo/security/equinox/EquinoxSecurity.java
deleted file mode 100644 (file)
index 00f9faa..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.argeo.security.equinox;
-
-import java.net.URL;
-
-import org.eclipse.equinox.security.auth.ILoginContext;
-import org.eclipse.equinox.security.auth.LoginContextFactory;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class EquinoxSecurity implements BundleActivator {
-       public final static String CONTEXT_SPRING = "SPRING";
-       private static final String JAAS_CONFIG_FILE = "org/argeo/security/equinox/jaas_default.txt";
-
-       private static ILoginContext loginContext = null;
-
-       public void start(BundleContext bundleContext) throws Exception {
-               // getLoginContext();
-               URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE);
-               loginContext = LoginContextFactory.createContext(CONTEXT_SPRING,
-                               configUrl);
-       }
-
-       public void stop(BundleContext context) throws Exception {
-       }
-
-       static ILoginContext getLoginContext() {
-               return loginContext;
-       }
-
-}
index d4361b2f67302ffa61eb697148d0969ed8347528..2222faeccf35620734bfebf9d1a4cd6a15fcc020 100644 (file)
@@ -10,8 +10,6 @@ import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.TextOutputCallback;
 import javax.security.auth.login.LoginException;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.springframework.security.Authentication;
 import org.springframework.security.AuthenticationManager;
 import org.springframework.security.BadCredentialsException;
@@ -21,10 +19,7 @@ import org.springframework.security.providers.jaas.SecurityContextLoginModule;
 
 /** Login module which caches one subject per thread. */
 public class SpringLoginModule extends SecurityContextLoginModule {
-       private final static Log log = LogFactory.getLog(SpringLoginModule.class);
-
        private AuthenticationManager authenticationManager;
-//     private ThreadLocal<Subject> subject;
 
        private CallbackHandler callbackHandler;
 
@@ -36,7 +31,7 @@ public class SpringLoginModule extends SecurityContextLoginModule {
        public void initialize(Subject subject, CallbackHandler callbackHandler,
                        Map sharedState, Map options) {
                super.initialize(subject, callbackHandler, sharedState, options);
-//             this.subject.set(subject);
+               // this.subject.set(subject);
                this.callbackHandler = callbackHandler;
        }
 
@@ -45,68 +40,66 @@ public class SpringLoginModule extends SecurityContextLoginModule {
                if (SecurityContextHolder.getContext().getAuthentication() != null)
                        return super.login();
 
-//             if (getSubject().getPrincipals(Authentication.class).size() == 1) {
-//                     registerAuthentication(getSubject()
-//                                     .getPrincipals(Authentication.class).iterator().next());
-//                     return super.login();
-//             } else if (getSubject().getPrincipals(Authentication.class).size() > 1) {
-//                     throw new LoginException(
-//                                     "Multiple Authentication principals not supported: "
-//                                                     + getSubject().getPrincipals(Authentication.class));
-//             } else {
-                       // ask for username and password
-                       Callback label = new TextOutputCallback(
-                                       TextOutputCallback.INFORMATION, "Required login");
-                       NameCallback nameCallback = new NameCallback("User");
-                       PasswordCallback passwordCallback = new PasswordCallback(
-                                       "Password", false);
-
-                       if (callbackHandler == null) {
-                               throw new LoginException("No call back handler available");
-                               // return false;
-                       }
-                       try {
-                               callbackHandler.handle(new Callback[] { label, nameCallback,
-                                               passwordCallback });
-                       } catch (Exception e) {
-                               LoginException le = new LoginException(
-                                               "Callback handling failed");
-                               le.initCause(e);
-                               throw le;
-                       }
-
-                       // Set user name and password
-                       String username = nameCallback.getName();
-                       String password = "";
-                       if (passwordCallback.getPassword() != null) {
-                               password = String.valueOf(passwordCallback.getPassword());
-                       }
-                       UsernamePasswordAuthenticationToken credentials = new UsernamePasswordAuthenticationToken(
-                                       username, password);
-
-                       try {
-                               Authentication authentication = authenticationManager
-                                               .authenticate(credentials);
-                               registerAuthentication(authentication);
-                               boolean res = super.login();
-//                             if (log.isDebugEnabled())
-//                                     log.debug("User " + username + " logged in");
-                               return res;
-                       } catch (BadCredentialsException bce) {
-                               throw bce;
-                       } catch (Exception e) {
-                               LoginException loginException = new LoginException(
-                                               "Bad credentials");
-                               loginException.initCause(e);
-                               throw loginException;
-                       }
-//             }
+               // if (getSubject().getPrincipals(Authentication.class).size() == 1) {
+               // registerAuthentication(getSubject()
+               // .getPrincipals(Authentication.class).iterator().next());
+               // return super.login();
+               // } else if (getSubject().getPrincipals(Authentication.class).size() >
+               // 1) {
+               // throw new LoginException(
+               // "Multiple Authentication principals not supported: "
+               // + getSubject().getPrincipals(Authentication.class));
+               // } else {
+               // ask for username and password
+               Callback label = new TextOutputCallback(TextOutputCallback.INFORMATION,
+                               "Required login");
+               NameCallback nameCallback = new NameCallback("User");
+               PasswordCallback passwordCallback = new PasswordCallback("Password",
+                               false);
+
+               if (callbackHandler == null) {
+                       throw new LoginException("No call back handler available");
+                       // return false;
+               }
+               try {
+                       callbackHandler.handle(new Callback[] { label, nameCallback,
+                                       passwordCallback });
+               } catch (Exception e) {
+                       LoginException le = new LoginException("Callback handling failed");
+                       le.initCause(e);
+                       throw le;
+               }
+
+               // Set user name and password
+               String username = nameCallback.getName();
+               String password = "";
+               if (passwordCallback.getPassword() != null) {
+                       password = String.valueOf(passwordCallback.getPassword());
+               }
+               UsernamePasswordAuthenticationToken credentials = new UsernamePasswordAuthenticationToken(
+                               username, password);
+
+               try {
+                       Authentication authentication = authenticationManager
+                                       .authenticate(credentials);
+                       registerAuthentication(authentication);
+                       boolean res = super.login();
+                       // if (log.isDebugEnabled())
+                       // log.debug("User " + username + " logged in");
+                       return res;
+               } catch (BadCredentialsException bce) {
+                       throw bce;
+               } catch (Exception e) {
+                       LoginException loginException = new LoginException(
+                                       "Bad credentials");
+                       loginException.initCause(e);
+                       throw loginException;
+               }
+               // }
        }
 
        @Override
        public boolean logout() throws LoginException {
-               if (log.isDebugEnabled())
-                       log.debug("Log out "+CurrentUser.getUsername());
                return super.logout();
        }
 
@@ -126,8 +119,8 @@ public class SpringLoginModule extends SecurityContextLoginModule {
                this.authenticationManager = authenticationManager;
        }
 
-//     protected Subject getSubject() {
-//             return subject.get();
-//     }
+       // protected Subject getSubject() {
+       // return subject.get();
+       // }
 
 }
diff --git a/security/eclipse/plugins/org.argeo.security.equinox/src/main/resources/org/argeo/security/equinox/jaas_default.txt b/security/eclipse/plugins/org.argeo.security.equinox/src/main/resources/org/argeo/security/equinox/jaas_default.txt
deleted file mode 100644 (file)
index b6cbaa6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-UNIX {
-    org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
-        extensionId="org.argeo.security.equinox.unixLoginModule";
-};
-
-SPRING {
-    org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
-        extensionId="org.argeo.security.equinox.springLoginModule";
-};
-
-SPRING_SECURITY_CONTEXT {
-    org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
-        extensionId="org.argeo.security.equinox.springSecurityContextLoginModule";
-};
\ No newline at end of file
diff --git a/security/eclipse/plugins/org.argeo.security.ui.application/META-INF/jaas_default.txt b/security/eclipse/plugins/org.argeo.security.ui.application/META-INF/jaas_default.txt
new file mode 100644 (file)
index 0000000..b6cbaa6
--- /dev/null
@@ -0,0 +1,14 @@
+UNIX {
+    org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
+        extensionId="org.argeo.security.equinox.unixLoginModule";
+};
+
+SPRING {
+    org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
+        extensionId="org.argeo.security.equinox.springLoginModule";
+};
+
+SPRING_SECURITY_CONTEXT {
+    org.eclipse.equinox.security.auth.module.ExtensionLoginModule sufficient
+        extensionId="org.argeo.security.equinox.springSecurityContextLoginModule";
+};
\ No newline at end of file
index 50c1f3ca2ce59bc0ea75d65806b236c27e423784..574dcc77ef8d67465800c9f18c8f006fe588740f 100644 (file)
@@ -35,7 +35,6 @@
       <plugin id="com.springsource.org.apache.commons.collections"/>
       <plugin id="com.springsource.org.apache.commons.io"/>
       <plugin id="com.springsource.org.apache.commons.lang"/>
-      <plugin id="com.springsource.org.apache.commons.logging"/>
       <plugin id="com.springsource.org.apache.commons.pool"/>
       <plugin id="com.springsource.org.apache.directory.server.changepw"/>
       <plugin id="com.springsource.org.apache.directory.server.core" fragment="true"/>
@@ -63,6 +62,7 @@
       <plugin id="org.argeo.eclipse.ui"/>
       <plugin id="org.argeo.security.core"/>
       <plugin id="org.argeo.security.equinox"/>
+      <plugin id="org.argeo.security.ldap"/>
       <plugin id="org.argeo.security.manager.ldap"/>
       <plugin id="org.argeo.security.services"/>
       <plugin id="org.argeo.security.ui"/>
@@ -71,6 +71,7 @@
       <plugin id="org.argeo.server.ads.server"/>
       <plugin id="org.argeo.server.core"/>
       <plugin id="org.argeo.server.json"/>
+      <plugin id="org.argeo.slc.demo.log4j" fragment="true"/>
       <plugin id="org.eclipse.core.commands"/>
       <plugin id="org.eclipse.core.contenttype"/>
       <plugin id="org.eclipse.core.databinding"/>
index 1fd2973a4b07ef37cb594dec64bc27d44b643854..e86c48750275bf998694c4a4b0328a188b134544 100644 (file)
@@ -1,4 +1,5 @@
-<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">
+<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.commons.security</groupId>
@@ -29,6 +30,7 @@
                                <version>${version.maven-bundle-plugin}</version>
                                <configuration>
                                        <instructions>
+                                               <Bundle-Activator>org.argeo.security.ui.application.SecureApplicationActivator</Bundle-Activator>
                                                <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
                                                <Require-Bundle>org.eclipse.ui;resolution:=optional,org.eclipse.rap.ui;resolution:=optional,org.eclipse.core.runtime</Require-Bundle>
                                                <Import-Package>*</Import-Package>
                <!-- Argeo Security -->
                <dependency>
                        <groupId>org.argeo.commons.security</groupId>
-                       <artifactId>org.argeo.security.equinox</artifactId>
+                       <artifactId>org.argeo.security.ui</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.security</groupId>
-                       <artifactId>org.argeo.security.ui</artifactId>
+                       <artifactId>org.argeo.security.equinox</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                </dependency>
+
+               <!-- Argeo Eclipse distribution (common dependencies for both RAP and RCP) -->
                <dependency>
-                       <groupId>org.argeo.commons.server</groupId>
-                       <artifactId>org.argeo.server.dep.ads</artifactId>
+                       <groupId>org.argeo.commons.eclipse</groupId>
+                       <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
-                       <type>pom</type>
+                       <scope>provided</scope>
+               </dependency>
+
+               <!-- Commons -->
+               <dependency>
+                       <groupId>org.argeo.commons.basic</groupId>
+                       <artifactId>org.argeo.basic.nodeps</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+               </dependency>
+
+
+               <!-- Others -->
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
                </dependency>
+
+               <!-- For testing and target platform generation -->
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.ads.server</artifactId>
                        <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.security</groupId>
                        <artifactId>org.argeo.security.services</artifactId>
                        <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.ldap</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.security</groupId>
                        <artifactId>org.argeo.security.manager.ldap</artifactId>
                        <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.ads</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
+                       <scope>test</scope>
                </dependency>
                <dependency>
                        <groupId>org.argeo.dep.osgi</groupId>
                        <artifactId>org.argeo.dep.osgi.springframework.ldap</artifactId>
+                       <scope>test</scope>
                </dependency>
-
-               <!-- Argeo Eclipse distribution (common dependencies for both RAP and RCP) -->
-               <dependency>
-                       <groupId>org.argeo.commons.eclipse</groupId>
-                       <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
-               </dependency>
-               
-               <!-- TODO: to be removed -->
-               <dependency>
-                       <groupId>org.argeo.commons.server</groupId>
-                       <artifactId>org.argeo.server.json</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
-               </dependency>
-
-               <!-- Commons -->
-               <dependency>
-                       <groupId>org.argeo.commons.basic</groupId>
-                       <artifactId>org.argeo.basic.nodeps</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
-               </dependency>
-
-
-               <!-- Others -->
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
-               </dependency>
-               <!-- Commons Dep -->
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.basic.dep.log4j</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                        <type>pom</type>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>net.sourceforge.jdbm</groupId>
+                       <artifactId>com.springsource.jdbm</artifactId>
+                       <scope>test</scope>
                </dependency>
        </dependencies>
 </project>
index 3a92e5273058ca2914e3253bc84787cf3d3c5d27..a0a2f922bbe31bc16384c087a80cf64c613582ff 100644 (file)
@@ -6,7 +6,6 @@ import javax.security.auth.Subject;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.argeo.security.equinox.CurrentUser;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.equinox.app.IApplication;
@@ -34,12 +33,18 @@ public abstract class AbstractSecureApplication implements IApplication {
                try {
                        String username = null;
                        Exception loginException = null;
+                       Subject subject = null;
                        try {
-                               username = CurrentUser.getUsername();
+                               SecureApplicationActivator.getLoginContext().login();
+                               subject = SecureApplicationActivator.getLoginContext()
+                                               .getSubject();
+
+                               // username = CurrentUser.getUsername();
                        } catch (Exception e) {
                                loginException = e;
+                               e.printStackTrace();
                        }
-                       if (username == null) {
+                       if (subject == null) {
                                IStatus status = new Status(IStatus.ERROR,
                                                "org.argeo.security.application", "Login is mandatory",
                                                loginException);
@@ -48,9 +53,8 @@ public abstract class AbstractSecureApplication implements IApplication {
                        }
                        if (log.isDebugEnabled())
                                log.debug("Logged in as " + username);
-                       returnCode = (Integer) Subject.doAs(CurrentUser.getSubject(),
-                                       getRunAction(display));
-                       CurrentUser.logout();
+                       returnCode = (Integer) Subject.doAs(subject, getRunAction(display));
+                       SecureApplicationActivator.getLoginContext().logout();
                        return processReturnCode(returnCode);
                } catch (Exception e) {
                        // e.printStackTrace();
@@ -104,9 +108,9 @@ public abstract class AbstractSecureApplication implements IApplication {
 
                if (log.isDebugEnabled())
                        log.debug("workbench stopped");
-               String username = CurrentUser.getUsername();
-               if (log.isDebugEnabled())
-                       log.debug("workbench stopped, logged in as " + username);
+               // String username = CurrentUser.getUsername();
+               // if (log.isDebugEnabled())
+               // log.debug("workbench stopped, logged in as " + username);
 
        }
 
diff --git a/security/eclipse/plugins/org.argeo.security.ui.application/src/main/java/org/argeo/security/ui/application/SecureApplicationActivator.java b/security/eclipse/plugins/org.argeo.security.ui.application/src/main/java/org/argeo/security/ui/application/SecureApplicationActivator.java
new file mode 100644 (file)
index 0000000..ec5d625
--- /dev/null
@@ -0,0 +1,29 @@
+package org.argeo.security.ui.application;
+
+import java.net.URL;
+
+import org.eclipse.equinox.security.auth.ILoginContext;
+import org.eclipse.equinox.security.auth.LoginContextFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class SecureApplicationActivator implements BundleActivator {
+
+       public final static String CONTEXT_SPRING = "SPRING";
+       private static final String JAAS_CONFIG_FILE = "/META-INF/jaas_default.txt";
+
+       private static ILoginContext loginContext = null;
+
+       public void start(BundleContext bundleContext) throws Exception {
+               URL configUrl = bundleContext.getBundle().getEntry(JAAS_CONFIG_FILE);
+               loginContext = LoginContextFactory.createContext(CONTEXT_SPRING,
+                               configUrl);
+       }
+
+       public void stop(BundleContext context) throws Exception {
+       }
+
+       static ILoginContext getLoginContext() {
+               return loginContext;
+       }
+}
index 92151771f268356e5176a821a0e3b8adb473e7e8..764c63f1cc9ad3b99dc7f2656e0687e567ee4736 100644 (file)
@@ -1,4 +1,5 @@
-<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">
+<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.commons.security</groupId>
                        <artifactId>org.argeo.eclipse.dep.rap</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                </dependency>
+
+
+               <!-- TODO: factorize with application.ui -->
+               <!-- For testing and target platform generation -->
+               <dependency>
+                       <groupId>org.argeo.commons.server</groupId>
+                       <artifactId>org.argeo.server.ads.server</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.services</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.ldap</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.manager.ldap</artifactId>
+                       <version>${version.argeo-commons}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.server</groupId>
+                       <artifactId>org.argeo.server.ads</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.dep.osgi</groupId>
+                       <artifactId>org.argeo.dep.osgi.springframework.ldap</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.basic</groupId>
+                       <artifactId>org.argeo.basic.dep.log4j</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+                       <type>pom</type>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>net.sourceforge.jdbm</groupId>
+                       <artifactId>com.springsource.jdbm</artifactId>
+                       <scope>test</scope>
+               </dependency>
        </dependencies>
 </project>
index f4fb717d487ba7855591e3491e5141064d60453b..0d9ed3165196ca375638d208e92d3dc95a6b1012 100644 (file)
@@ -1,4 +1,5 @@
-<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">
+<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.commons.security</groupId>
                                <artifactId>maven-bundle-plugin</artifactId>
                                <version>${version.maven-bundle-plugin}</version>
                                <configuration>
+                                       <!-- <instructions> -->
+                                       <!-- <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy> -->
+                                       <!-- <Bundle-Activator>org.argeo.security.ui.SecurityUiPlugin</Bundle-Activator> -->
+                                       <!-- <Require-Bundle>org.eclipse.ui;resolution:=optional,org.eclipse.rap.ui;resolution:=optional,org.eclipse.core.runtime</Require-Bundle> -->
+                                       <!-- <Import-Package> -->
+                                       <!-- org.argeo.eclipse.spring, -->
+                                       <!-- org.osgi.framework;version="0.0.0", -->
+                                       <!-- !org.eclipse.core.runtime, -->
+                                       <!-- !org.eclipse.core.commands, -->
+                                       <!-- !org.eclipse.ui.plugin, -->
+                                       <!-- !org.eclipse.ui, -->
+                                       <!-- !org.eclipse.ui.commands, -->
+                                       <!-- !org.eclipse.ui.handlers, -->
+                                       <!-- !org.eclipse.ui.part, -->
+                                       <!-- * -->
+                                       <!-- </Import-Package> -->
+                                       <!-- <Private-Package>icons</Private-Package> -->
+                                       <!-- <Export-Package>org.argeo.security.ui.*</Export-Package> -->
+                                       <!-- </instructions> -->
                                        <instructions>
                                                <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy>
                                                <Bundle-Activator>org.argeo.security.ui.SecurityUiPlugin</Bundle-Activator>
                                                <Require-Bundle>org.eclipse.ui;resolution:=optional,org.eclipse.rap.ui;resolution:=optional,org.eclipse.core.runtime</Require-Bundle>
-                                               <Import-Package>*,org.argeo.eclipse.spring</Import-Package>
+                                               <Import-Package>
+                                                       org.argeo.eclipse.spring,
+                                                       *
+                                               </Import-Package>
                                        </instructions>
                                </configuration>
                        </plugin>
                        <artifactId>org.argeo.security.core</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                </dependency>
-               <dependency>
-                       <groupId>org.argeo.commons.security</groupId>
-                       <artifactId>org.argeo.security.equinox</artifactId>
-                       <version>0.2.3-SNAPSHOT</version>
-               </dependency>
 
                <!-- Argeo Eclipse -->
                <dependency>
                        <groupId>org.argeo.commons.eclipse</groupId>
                        <artifactId>org.argeo.eclipse.dep.rcp</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.eclipse.ui</groupId>
-                       <artifactId>org.eclipse.ui</artifactId>
                        <scope>provided</scope>
                </dependency>
 
                        <groupId>org.slf4j</groupId>
                        <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
                </dependency>
-
        </dependencies>
 </project>
diff --git a/security/eclipse/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/CurrentUser.java b/security/eclipse/plugins/org.argeo.security.ui/src/main/java/org/argeo/security/ui/CurrentUser.java
new file mode 100644 (file)
index 0000000..a864c3a
--- /dev/null
@@ -0,0 +1,43 @@
+package org.argeo.security.ui;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+import org.argeo.ArgeoException;
+import org.springframework.security.Authentication;
+import org.springframework.security.GrantedAuthority;
+
+public class CurrentUser {
+       public final static String getUsername() {
+               Subject subject = getSubject();
+               if (subject == null)
+                       return null;
+               Principal principal = subject.getPrincipals().iterator().next();
+               return principal.getName();
+
+       }
+
+       public final static Set<String> roles() {
+               Principal principal = getSubject().getPrincipals().iterator().next();
+               Authentication authentication = (Authentication) principal;
+               Set<String> roles = Collections.synchronizedSet(new HashSet<String>());
+               for (GrantedAuthority ga : authentication.getAuthorities()) {
+                       roles.add(ga.getAuthority());
+               }
+               return Collections.unmodifiableSet(roles);
+       }
+
+       public final static Subject getSubject() {
+
+               Subject subject = Subject.getSubject(AccessController.getContext());
+               if (subject == null)
+                       throw new ArgeoException("Not authenticated.");
+               return subject;
+
+       }
+}
index 9187c7830a4c1beeed9a68967cf1a1117b15eb13..3b3b9b840a6c58ed29c87aa8e3cd062ae7d176f7 100644 (file)
@@ -1,6 +1,5 @@
 package org.argeo.security.ui;
 
-import org.argeo.security.equinox.CurrentUser;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IFolderLayout;
index 263a722e74912ae9050e33e8b1f9ff292671e896..5b049282886e9266d20d975c86bb81e4ec13df6f 100644 (file)
@@ -1,6 +1,6 @@
 package org.argeo.security.ui.views;
 
-import org.argeo.security.equinox.CurrentUser;
+import org.argeo.security.ui.CurrentUser;
 import org.eclipse.jface.viewers.IStructuredContentProvider;
 import org.eclipse.jface.viewers.ITableLabelProvider;
 import org.eclipse.jface.viewers.LabelProvider;
@@ -46,9 +46,9 @@ public class CurrentUserView extends ViewPart {
                column.setText("ID");
                column.setWidth(100);
 
-//             column = new TableColumn(table, SWT.LEFT, 1);
-//             column.setText("Password");
-//             column.setWidth(200);
+               // column = new TableColumn(table, SWT.LEFT, 1);
+               // column.setText("Password");
+               // column.setWidth(200);
 
                // column = new TableColumn(table, SWT.LEFT, 2);
                // column.setText("Roles");
@@ -69,26 +69,26 @@ public class CurrentUserView extends ViewPart {
                }
 
                public Object[] getChildren(Object parentElement) {
-//                     ILoginContext secureContext = LoginContextFactory
-//                                     .createContext("SPRING");
-//                     try {
-//                             secureContext.login();
-//                     } catch (LoginException e) {
-//                             // login failed
-//                     }
-//
-//                     Subject subject = null;
-//                     // subject = Subject.getSubject(AccessController.getContext());
-//                     try {
-//                             subject = secureContext.getSubject();
-//                     } catch (Exception e) {
-//                             e.printStackTrace();
-//                             throw new ArgeoException("Cannot retrieve subject", e);
-//                     }
-//
-//                     if (subject == null)
-//                             throw new ArgeoException("No subject found");
-//                     return subject.getPrincipals().toArray();
+                       // ILoginContext secureContext = LoginContextFactory
+                       // .createContext("SPRING");
+                       // try {
+                       // secureContext.login();
+                       // } catch (LoginException e) {
+                       // // login failed
+                       // }
+                       //
+                       // Subject subject = null;
+                       // // subject = Subject.getSubject(AccessController.getContext());
+                       // try {
+                       // subject = secureContext.getSubject();
+                       // } catch (Exception e) {
+                       // e.printStackTrace();
+                       // throw new ArgeoException("Cannot retrieve subject", e);
+                       // }
+                       //
+                       // if (subject == null)
+                       // throw new ArgeoException("No subject found");
+                       // return subject.getPrincipals().toArray();
                        return CurrentUser.roles().toArray();
                }
 
@@ -107,15 +107,15 @@ public class CurrentUserView extends ViewPart {
        private class UsersLabelProvider extends LabelProvider implements
                        ITableLabelProvider {
                public String getColumnText(Object element, int columnIndex) {
-//                     Principal argeoUser = (Principal) element;
-//                     switch (columnIndex) {
-//                     case 0:
-//                             return argeoUser.getName();
-//                     case 1:
-//                             return argeoUser.toString();
-//                     default:
-//                             throw new ArgeoException("Unmanaged column " + columnIndex);
-//                     }
+                       // Principal argeoUser = (Principal) element;
+                       // switch (columnIndex) {
+                       // case 0:
+                       // return argeoUser.getName();
+                       // case 1:
+                       // return argeoUser.toString();
+                       // default:
+                       // throw new ArgeoException("Unmanaged column " + columnIndex);
+                       // }
                        return element.toString();
                }
 
index d77ad0e07f154471f1f9fc71976cc4ef4d09a3b8..5d78178273cadd324076c16ca57a0d1a22c50cc1 100644 (file)
@@ -5,8 +5,8 @@ import java.util.ArrayList;
 import org.argeo.ArgeoException;
 import org.argeo.security.ArgeoSecurityService;
 import org.argeo.security.ArgeoUser;
-import org.argeo.security.equinox.CurrentUser;
 import org.argeo.security.nature.SimpleUserNature;
+import org.argeo.security.ui.CurrentUser;
 import org.argeo.security.ui.SecurityUiPlugin;
 import org.argeo.security.ui.commands.OpenArgeoUserEditor;
 import org.eclipse.core.commands.Command;
index e953b71a816534369ad04576e09b56a7740ca82f..ab837feb5d6251fd6a43d0da49786245d3ee754f 100644 (file)
                        <version>0.2.3-SNAPSHOT</version>
                        <scope>test</scope>
                </dependency>
+               <dependency>
+                       <groupId>javax.xml.stream</groupId>
+                       <artifactId>com.springsource.javax.xml.stream</artifactId>
+                       <scope>test</scope>
+               </dependency>
        </dependencies>
 </project>
diff --git a/security/runtime/org.argeo.security.activemq/.classpath b/security/runtime/org.argeo.security.activemq/.classpath
new file mode 100644 (file)
index 0000000..92f19d2
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src/main/java"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/security/runtime/org.argeo.security.activemq/.project b/security/runtime/org.argeo.security.activemq/.project
new file mode 100644 (file)
index 0000000..cdc841c
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.security.activemq</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/security/runtime/org.argeo.security.activemq/.settings/org.eclipse.jdt.core.prefs b/security/runtime/org.argeo.security.activemq/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..312bbe1
--- /dev/null
@@ -0,0 +1,8 @@
+#Wed Feb 16 10:40:27 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/security/runtime/org.argeo.security.activemq/.settings/org.eclipse.pde.core.prefs b/security/runtime/org.argeo.security.activemq/.settings/org.eclipse.pde.core.prefs
new file mode 100644 (file)
index 0000000..85f2008
--- /dev/null
@@ -0,0 +1,4 @@
+#Wed Feb 16 10:40:27 CET 2011
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/security/runtime/org.argeo.security.activemq/build.properties b/security/runtime/org.argeo.security.activemq/build.properties
new file mode 100644 (file)
index 0000000..5fc538b
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/main/java/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .
diff --git a/security/runtime/org.argeo.security.activemq/pom.xml b/security/runtime/org.argeo.security.activemq/pom.xml
new file mode 100644 (file)
index 0000000..0405a5c
--- /dev/null
@@ -0,0 +1,89 @@
+<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.commons.security</groupId>
+               <artifactId>runtime</artifactId>
+               <version>0.2.3-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.security.activemq</artifactId>
+       <name>Commons Security ActiveMQ</name>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-source-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <version>${version.maven-bundle-plugin}</version>
+                               <configuration>
+                                       <instructions>
+                                               <Export-Package>
+                                                       org.argeo.security.activemq.*
+                                               </Export-Package>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       <dependencies>
+               <dependency>
+                       <groupId>org.argeo.commons.basic</groupId>
+                       <artifactId>org.argeo.basic.nodeps</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.core</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+               </dependency>
+
+               <!-- Spring -->
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.transaction</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.security</groupId>
+                       <artifactId>org.springframework.security.core</artifactId>
+               </dependency>
+
+               <!-- Logging -->
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
+               </dependency>
+
+               <!-- JMS -->
+               <dependency>
+                       <groupId>org.argeo.dep.osgi</groupId>
+                       <artifactId>org.argeo.dep.osgi.activemq</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>javax.jms</groupId>
+                       <artifactId>com.springsource.javax.jms</artifactId>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.jms</artifactId>
+               </dependency>
+
+               <!-- TEST -->
+               <dependency>
+                       <groupId>org.junit</groupId>
+                       <artifactId>com.springsource.junit</artifactId>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+</project>
diff --git a/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/ActiveMqSecurityBrokerPlugin.java b/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/ActiveMqSecurityBrokerPlugin.java
new file mode 100644 (file)
index 0000000..f389145
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.activemq;
+
+import org.apache.activemq.broker.BrokerPluginSupport;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ConnectionInfo;
+import org.argeo.ArgeoException;
+import org.argeo.security.core.InternalAuthentication;
+import org.springframework.security.Authentication;
+import org.springframework.security.AuthenticationManager;
+import org.springframework.security.context.SecurityContext;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
+
+public class ActiveMqSecurityBrokerPlugin extends BrokerPluginSupport {
+//     private final static Log log = LogFactory
+//                     .getLog(ActiveMqSecurityBrokerPlugin.class);
+
+       private AuthenticationManager authenticationManager;
+       private String systemUsername = InternalAuthentication.DEFAULT_SYSTEM_USERNAME;
+       private String systemRole = InternalAuthentication.DEFAULT_SYSTEM_ROLE;
+
+       @Override
+       public void addConnection(ConnectionContext context, ConnectionInfo info)
+                       throws Exception {
+               String username = info.getUserName();
+               if (username == null)
+                       throw new ArgeoException("No user name provided");
+               String password = info.getPassword();
+               if (password == null) {
+                       password = context.getConnection().getRemoteAddress().substring(1);
+                       password = password.substring(0, password.lastIndexOf(':'));
+               }
+
+               SecurityContext securityContext = SecurityContextHolder.getContext();
+
+               final Authentication authRequest;
+               if (username.equals(systemUsername))
+                       authRequest = new InternalAuthentication(password, username,
+                                       systemRole);
+               else
+                       authRequest = new UsernamePasswordAuthenticationToken(username,
+                                       password);
+
+               final Authentication auth = authenticationManager
+                               .authenticate(authRequest);
+               securityContext.setAuthentication(auth);
+               context.setSecurityContext(new ActiveMqSpringSecurityContext(
+                               securityContext));
+
+               super.addConnection(context, info);
+       }
+
+       public void setAuthenticationManager(
+                       AuthenticationManager authenticationManager) {
+               this.authenticationManager = authenticationManager;
+       }
+
+       public void setSystemUsername(String systemUsername) {
+               this.systemUsername = systemUsername;
+       }
+
+       public void setSystemRole(String systemRole) {
+               this.systemRole = systemRole;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/ActiveMqSpringSecurityContext.java b/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/ActiveMqSpringSecurityContext.java
new file mode 100644 (file)
index 0000000..bb35cdb
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.activemq;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.context.SecurityContext;
+
+public class ActiveMqSpringSecurityContext extends
+               org.apache.activemq.security.SecurityContext {
+
+       private final SecurityContext springSecurityContext;
+
+       public ActiveMqSpringSecurityContext(SecurityContext springSecurityContext) {
+               super(springSecurityContext.getAuthentication().getName());
+               this.springSecurityContext = springSecurityContext;
+       }
+
+       @Override
+       public Set<?> getPrincipals() {
+               return new HashSet<GrantedAuthority>(Arrays
+                               .asList(springSecurityContext.getAuthentication()
+                                               .getAuthorities()));
+       }
+
+       public SecurityContext getSpringSecurityContext() {
+               return springSecurityContext;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/SecuredActiveMqConnectionFactory.java b/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/SecuredActiveMqConnectionFactory.java
new file mode 100644 (file)
index 0000000..4afbd1d
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.activemq;
+
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.TrustManagerFactory;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+
+import org.apache.activemq.ActiveMQSslConnectionFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.core.io.Resource;
+import org.springframework.jms.connection.CachingConnectionFactory;
+import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter;
+
+public class SecuredActiveMqConnectionFactory implements ConnectionFactory,
+               InitializingBean, DisposableBean {
+
+       public final static String AUTHMODE_UI = "ui";
+       public final static String AUTHMODE_OS = "os";
+       public final static String AUTHMODE_DEFAULT = AUTHMODE_OS;
+       // private final static String LOGIN_CONFIG_PROPERTY =
+       // "java.security.auth.login.config";
+
+       private final static Log log = LogFactory
+                       .getLog(SecuredActiveMqConnectionFactory.class);
+
+       private String keyStorePassword;
+       private Resource keyStore;
+       private String keyStoreType = "JKS";// "PKCS12"
+       private String brokerURL;
+
+       private String authenticationMode;
+
+       private CachingConnectionFactory cachingConnectionFactory;
+
+       public Connection createConnection() throws JMSException {
+               return cachingConnectionFactory.createConnection();
+       }
+
+       public Connection createConnection(String userName, String password)
+                       throws JMSException {
+               throw new UnsupportedOperationException();
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               ActiveMQSslConnectionFactory activeMQSslConnectionFactory = new ActiveMQSslConnectionFactory();
+               prepareActiveMqSslConnectionFactory(activeMQSslConnectionFactory);
+               activeMQSslConnectionFactory.setBrokerURL(brokerURL);
+               UserCredentialsConnectionFactoryAdapter uccfa = new UserCredentialsConnectionFactoryAdapter();
+               uccfa.setTargetConnectionFactory(activeMQSslConnectionFactory);
+               cachingConnectionFactory = new CachingConnectionFactory();
+               cachingConnectionFactory.setTargetConnectionFactory(uccfa);
+               cachingConnectionFactory.setCacheConsumers(false);
+
+               initConnectionFactoryCredentials(uccfa);
+               cachingConnectionFactory.initConnection();
+               log.info("Connected to " + brokerURL);
+               uccfa.setUsername(null);
+               uccfa.setPassword(null);
+
+       }
+
+       protected void initConnectionFactoryCredentials(
+                       final UserCredentialsConnectionFactoryAdapter uccfa) {
+               if (authenticationMode == null)
+                       authenticationMode = AUTHMODE_DEFAULT;
+
+               if (AUTHMODE_OS.equals(authenticationMode)) {
+                       // if (false) {
+                       // // Cache previous value of login conf location
+                       // String oldLoginConfLocation = System
+                       // .getProperty(LOGIN_CONFIG_PROPERTY);
+                       // // Find OS family
+                       // String osName = System.getProperty("os.name");
+                       // final String auth;
+                       // if (osName.startsWith("Windows"))
+                       // auth = "Windows";
+                       // else if (osName.startsWith("SunOS")
+                       // || osName.startsWith("Solaris"))
+                       // auth = "Solaris";
+                       // else
+                       // auth = "Unix";
+                       //
+                       // Subject subject;
+                       // // see http://old.nabble.com/osgi-and-jaas-td23485885.html
+                       // ClassLoader ccl = Thread.currentThread()
+                       // .getContextClassLoader();
+                       // try {
+                       // Thread.currentThread().setContextClassLoader(
+                       // getClass().getClassLoader());
+                       // URL url = getClass().getResource(
+                       // "/org/argeo/security/activemq/osLogin.conf");
+                       //
+                       // System.setProperty(LOGIN_CONFIG_PROPERTY, url.toString());
+                       // LoginContext lc = new LoginContext(auth);
+                       // lc.login();
+                       // subject = lc.getSubject();
+                       // } catch (LoginException le) {
+                       // throw new ArgeoException("OS authentication failed", le);
+                       // } finally {
+                       // if (oldLoginConfLocation != null)
+                       // System.setProperty(LOGIN_CONFIG_PROPERTY,
+                       // oldLoginConfLocation);
+                       // Thread.currentThread().setContextClassLoader(ccl);
+                       // }
+                       // // Extract user name
+                       // String osUsername = null;
+                       // for (Principal principal : subject.getPrincipals()) {
+                       // String className = principal.getClass().getName();
+                       // if ("Unix".equals(auth)
+                       // && "com.sun.security.auth.UnixPrincipal"
+                       // .equals(className))
+                       // osUsername = principal.getName();
+                       // else if ("Windows".equals(auth)
+                       // && "com.sun.security.auth.NTUserPrincipal"
+                       // .equals(className))
+                       // osUsername = principal.getName();
+                       // else if ("Solaris".equals(auth)
+                       // && "com.sun.security.auth.SolarisPrincipal"
+                       // .equals(className))
+                       // osUsername = principal.getName();
+                       // }
+                       //
+                       // if (osUsername == null)
+                       // throw new ArgeoException("Could not find OS user name");
+                       // }
+
+                       uccfa.setUsername(System.getProperty("user.name"));
+                       uccfa.setPassword(null);
+
+               } else if (AUTHMODE_UI.equals(authenticationMode)) {
+                       try {
+                               UIManager.setLookAndFeel(new MetalLookAndFeel());
+                       } catch (UnsupportedLookAndFeelException e) {
+                               throw new ArgeoException("Cannot load look and feel", e);
+                       }
+                       UIManager.put("ClassLoader", getClass().getClassLoader());
+                       UserPasswordDialog dialog = new UserPasswordDialog() {
+                               private static final long serialVersionUID = -891646559691412088L;
+
+                               protected void useCredentials(String username, char[] password) {
+                                       uccfa.setUsername(username);
+                                       uccfa.setPassword(new String(password));
+                               }
+                       };
+                       dialog.setVisible(true);
+               } else {
+                       throw new ArgeoException("Authentication mode '"
+                                       + authenticationMode + "' is not supported");
+               }
+
+       }
+
+       protected void prepareActiveMqSslConnectionFactory(
+                       ActiveMQSslConnectionFactory connectionFactory) {
+               try {
+                       KeyStore keyStoreKs = KeyStore.getInstance(keyStoreType);
+
+                       InputStream keyInput = keyStore.getInputStream();
+                       keyStoreKs.load(keyInput,
+                                       keyStorePassword != null ? keyStorePassword.toCharArray()
+                                                       : null);
+                       keyInput.close();
+
+                       TrustManagerFactory tmf = TrustManagerFactory
+                                       .getInstance(TrustManagerFactory.getDefaultAlgorithm());
+                       tmf.init(keyStoreKs);
+
+                       KeyManagerFactory keyManagerFactory = KeyManagerFactory
+                                       .getInstance(KeyManagerFactory.getDefaultAlgorithm());
+                       keyManagerFactory.init(keyStoreKs, keyStorePassword.toCharArray());
+
+                       connectionFactory.setKeyAndTrustManagers(
+                                       keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(),
+                                       new SecureRandom());
+               } catch (Exception e) {
+                       throw new ArgeoException(
+                                       "Cannot initialize JMS connection factory", e);
+               }
+
+       }
+
+       public void destroy() throws Exception {
+               if (cachingConnectionFactory != null)
+                       cachingConnectionFactory.destroy();
+       }
+
+       public void setKeyStorePassword(String keyStorePassword) {
+               this.keyStorePassword = keyStorePassword;
+       }
+
+       public void setKeyStore(Resource keyStore) {
+               this.keyStore = keyStore;
+       }
+
+       public void setKeyStoreType(String keyStoreType) {
+               this.keyStoreType = keyStoreType;
+       }
+
+       public void setBrokerURL(String brokerUrl) {
+               this.brokerURL = brokerUrl;
+       }
+
+       public void setAuthenticationMode(String authenticationMode) {
+               this.authenticationMode = authenticationMode;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/UserPasswordDialog.java b/security/runtime/org.argeo.security.activemq/src/main/java/org/argeo/security/activemq/UserPasswordDialog.java
new file mode 100644 (file)
index 0000000..6725076
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.activemq;
+
+import java.awt.Container;
+import java.awt.GridLayout;
+import java.awt.Panel;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Arrays;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+
+public class UserPasswordDialog extends JDialog implements ActionListener {
+       private static final long serialVersionUID = -9052993072210981198L;
+       private static String OK = "ok";
+
+       private JTextField username = new JTextField("", 10);
+       private JPasswordField password = new JPasswordField("", 10);
+
+       private JButton okButton;
+       private JButton cancelButton;
+
+       public UserPasswordDialog() {
+               setTitle("Credentials");
+               setModal(true);
+               setLocationRelativeTo(null);
+               setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+               JPanel p1 = new JPanel(new GridLayout(2, 2, 3, 3));
+               p1.add(new JLabel("User"));
+               p1.add(username);
+               p1.add(new JLabel("Password"));
+               password.setActionCommand(OK);
+               password.addActionListener(this);
+               p1.add(password);
+               add("Center", p1);
+
+               Panel p2 = new Panel();
+               okButton = addButton(p2, "OK");
+               okButton.setActionCommand(OK);
+               cancelButton = addButton(p2, "Cancel");
+               add("South", p2);
+               setSize(240, 120);
+
+               pack();
+       }
+
+       /** To be overridden */
+       protected void useCredentials(String username, char[] password) {
+               // does nothing
+       }
+
+       private JButton addButton(Container c, String name) {
+               JButton button = new JButton(name);
+               button.addActionListener(this);
+               c.add(button);
+               return button;
+       }
+
+       public final void actionPerformed(ActionEvent evt) {
+               Object source = evt.getSource();
+               if (source == okButton || evt.getActionCommand().equals(OK)) {
+                       char[] p = password.getPassword();
+                       useCredentials(username.getText(), p);
+                       Arrays.fill(p, '0');
+                       cleanUp();
+               } else if (source == cancelButton)
+                       cleanUp();
+       }
+
+       private void cleanUp() {
+               password.setText("");
+               dispose();
+       }
+
+       public static void main(String[] args) {
+               UserPasswordDialog dialog = new UserPasswordDialog() {
+                       private static final long serialVersionUID = -891646559691412088L;
+
+                       protected void useCredentials(String username, char[] password) {
+                               System.out.println(username + "/" + new String(password));
+                       }
+               };
+               dialog.setVisible(true);
+               System.out.println("After show");
+       }
+}
index a7129a37cdec2c85a376c3402baccafcd1c4d6c7..6ebf8f32f540d0bc1fe0ff5318557e659286f2c3 100644 (file)
@@ -9,7 +9,8 @@ additional.bundles = org.springframework.transaction,\
                      com.springsource.org.codehaus.jackson.mapper,\
                      com.springsource.org.apache.log4j,\
                      com.springsource.slf4j.api,\
-                     com.springsource.slf4j.org.apache.commons.logging
+                     com.springsource.slf4j.org.apache.commons.logging,\
+                     org.argeo.server.json
 source.. = src/main/java/,\
            src/main/resources/,\
            src/test/java/,\
index b3b53e32118060ea9e63311beeff1b432e840f23..b36f10d56e7dfddd7d0e48338a13e2774f46f48f 100644 (file)
@@ -1,4 +1,5 @@
-<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">
+<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.commons.security</groupId>
                                                <Export-Package>
                                                        org.argeo.security.*
                                                </Export-Package>
-                                               <Import-Package>*,
+                                               <Import-Package>
                                                        org.springframework.context,
-                                                       org.argeo.server.json;resolution:=optional,
-                                                       javax.jms;resolution:=optional,
-                                                       org.apache.activemq;resolution:=optional,
-                                                       org.apache.activemq.broker;resolution:=optional,
-                                                       org.apache.activemq.command;resolution:=optional,
-                                                       org.apache.activemq.security;resolution:=optional,
-                                                       org.springframework.jms.connection;resolution:=optional,
-                                                       org.springframework.ldap.core;resolution:=optional,
-                                                       org.springframework.ldap.core.support;resolution:=optional,
+                                                       org.springframework.beans.factory,
+                                                       *
                                                </Import-Package>
                                        </instructions>
                                </configuration>
                        <version>0.2.3-SNAPSHOT</version>
                </dependency>
 
-               <dependency>
-                       <!-- Force inclusion of commons.lang to prevent v2.1.0 to be taken by 
-                               Spring Security -->
-                       <groupId>org.apache.commons</groupId>
-                       <artifactId>com.springsource.org.apache.commons.lang</artifactId>
-               </dependency>
-
                <!-- Spring -->
                <dependency>
-                       <groupId>org.argeo.dep.osgi</groupId>
-                       <artifactId>org.argeo.dep.osgi.springframework.ldap</artifactId>
+                       <groupId>org.springframework</groupId>
+                       <artifactId>org.springframework.beans</artifactId>
                </dependency>
                <dependency>
                        <groupId>org.springframework</groupId>
-                       <artifactId>org.springframework.transaction</artifactId>
+                       <artifactId>org.springframework.context</artifactId>
                </dependency>
                <dependency>
                        <groupId>org.springframework.security</groupId>
                        <groupId>org.slf4j</groupId>
                        <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>org.apache.log4j</groupId>
-                       <artifactId>com.springsource.org.apache.log4j</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>com.springsource.slf4j.log4j</artifactId>
-               </dependency>
-
-               <!-- JSON -->
-               <dependency>
-                       <groupId>org.codehaus.jackson</groupId>
-                       <artifactId>com.springsource.org.codehaus.jackson.mapper</artifactId>
-               </dependency>
-
-               <dependency>
-                       <groupId>com.springsource.json</groupId>
-                       <artifactId>com.springsource.json</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.antlr</groupId>
-                       <artifactId>com.springsource.org.antlr</artifactId>
-               </dependency>
-
-               <!-- JMS -->
-               <dependency>
-                       <groupId>org.argeo.dep.osgi</groupId>
-                       <artifactId>org.argeo.dep.osgi.activemq</artifactId>
-                       <optional>true</optional>
-               </dependency>
-               <dependency>
-                       <groupId>javax.jms</groupId>
-                       <artifactId>com.springsource.javax.jms</artifactId>
-                       <optional>true</optional>
-               </dependency>
-               <dependency>
-                       <groupId>org.springframework</groupId>
-                       <artifactId>org.springframework.jms</artifactId>
-                       <optional>true</optional>
-               </dependency>
-
-<!--           <dependency>-->
-<!--                   <groupId>org.apache.commons</groupId>-->
-<!--                   <artifactId>com.springsource.org.apache.commons.codec</artifactId>-->
-<!--           </dependency>-->
 
                <!-- TEST -->
                <dependency>
                        <artifactId>com.springsource.junit</artifactId>
                        <scope>test</scope>
                </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.basic</groupId>
+                       <artifactId>org.argeo.basic.dep.log4j</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+                       <type>pom</type>
+                       <scope>test</scope>
+               </dependency>
                <dependency>
                        <groupId>org.argeo.commons.server</groupId>
                        <artifactId>org.argeo.server.json</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                        <scope>test</scope>
                </dependency>
+               <dependency>
+                       <groupId>com.springsource.json</groupId>
+                       <artifactId>com.springsource.json</artifactId>
+                       <scope>test</scope>
+               </dependency>
 
        </dependencies>
 </project>
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/ActiveMqSecurityBrokerPlugin.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/ActiveMqSecurityBrokerPlugin.java
deleted file mode 100644 (file)
index f389145..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.activemq;
-
-import org.apache.activemq.broker.BrokerPluginSupport;
-import org.apache.activemq.broker.ConnectionContext;
-import org.apache.activemq.command.ConnectionInfo;
-import org.argeo.ArgeoException;
-import org.argeo.security.core.InternalAuthentication;
-import org.springframework.security.Authentication;
-import org.springframework.security.AuthenticationManager;
-import org.springframework.security.context.SecurityContext;
-import org.springframework.security.context.SecurityContextHolder;
-import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
-
-public class ActiveMqSecurityBrokerPlugin extends BrokerPluginSupport {
-//     private final static Log log = LogFactory
-//                     .getLog(ActiveMqSecurityBrokerPlugin.class);
-
-       private AuthenticationManager authenticationManager;
-       private String systemUsername = InternalAuthentication.DEFAULT_SYSTEM_USERNAME;
-       private String systemRole = InternalAuthentication.DEFAULT_SYSTEM_ROLE;
-
-       @Override
-       public void addConnection(ConnectionContext context, ConnectionInfo info)
-                       throws Exception {
-               String username = info.getUserName();
-               if (username == null)
-                       throw new ArgeoException("No user name provided");
-               String password = info.getPassword();
-               if (password == null) {
-                       password = context.getConnection().getRemoteAddress().substring(1);
-                       password = password.substring(0, password.lastIndexOf(':'));
-               }
-
-               SecurityContext securityContext = SecurityContextHolder.getContext();
-
-               final Authentication authRequest;
-               if (username.equals(systemUsername))
-                       authRequest = new InternalAuthentication(password, username,
-                                       systemRole);
-               else
-                       authRequest = new UsernamePasswordAuthenticationToken(username,
-                                       password);
-
-               final Authentication auth = authenticationManager
-                               .authenticate(authRequest);
-               securityContext.setAuthentication(auth);
-               context.setSecurityContext(new ActiveMqSpringSecurityContext(
-                               securityContext));
-
-               super.addConnection(context, info);
-       }
-
-       public void setAuthenticationManager(
-                       AuthenticationManager authenticationManager) {
-               this.authenticationManager = authenticationManager;
-       }
-
-       public void setSystemUsername(String systemUsername) {
-               this.systemUsername = systemUsername;
-       }
-
-       public void setSystemRole(String systemRole) {
-               this.systemRole = systemRole;
-       }
-
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/ActiveMqSpringSecurityContext.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/ActiveMqSpringSecurityContext.java
deleted file mode 100644 (file)
index bb35cdb..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.activemq;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.springframework.security.GrantedAuthority;
-import org.springframework.security.context.SecurityContext;
-
-public class ActiveMqSpringSecurityContext extends
-               org.apache.activemq.security.SecurityContext {
-
-       private final SecurityContext springSecurityContext;
-
-       public ActiveMqSpringSecurityContext(SecurityContext springSecurityContext) {
-               super(springSecurityContext.getAuthentication().getName());
-               this.springSecurityContext = springSecurityContext;
-       }
-
-       @Override
-       public Set<?> getPrincipals() {
-               return new HashSet<GrantedAuthority>(Arrays
-                               .asList(springSecurityContext.getAuthentication()
-                                               .getAuthorities()));
-       }
-
-       public SecurityContext getSpringSecurityContext() {
-               return springSecurityContext;
-       }
-
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/SecuredActiveMqConnectionFactory.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/activemq/SecuredActiveMqConnectionFactory.java
deleted file mode 100644 (file)
index 95e6a69..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.activemq;
-
-import java.io.InputStream;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.JMSException;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.TrustManagerFactory;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-import javax.swing.plaf.metal.MetalLookAndFeel;
-
-import org.apache.activemq.ActiveMQSslConnectionFactory;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.argeo.ArgeoException;
-import org.argeo.security.core.UserPasswordDialog;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.core.io.Resource;
-import org.springframework.jms.connection.CachingConnectionFactory;
-import org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter;
-
-public class SecuredActiveMqConnectionFactory implements ConnectionFactory,
-               InitializingBean, DisposableBean {
-
-       public final static String AUTHMODE_UI = "ui";
-       public final static String AUTHMODE_OS = "os";
-       public final static String AUTHMODE_DEFAULT = AUTHMODE_OS;
-       // private final static String LOGIN_CONFIG_PROPERTY =
-       // "java.security.auth.login.config";
-
-       private final static Log log = LogFactory
-                       .getLog(SecuredActiveMqConnectionFactory.class);
-
-       private String keyStorePassword;
-       private Resource keyStore;
-       private String keyStoreType = "JKS";// "PKCS12"
-       private String brokerURL;
-
-       private String authenticationMode;
-
-       private CachingConnectionFactory cachingConnectionFactory;
-
-       public Connection createConnection() throws JMSException {
-               return cachingConnectionFactory.createConnection();
-       }
-
-       public Connection createConnection(String userName, String password)
-                       throws JMSException {
-               throw new UnsupportedOperationException();
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               ActiveMQSslConnectionFactory activeMQSslConnectionFactory = new ActiveMQSslConnectionFactory();
-               prepareActiveMqSslConnectionFactory(activeMQSslConnectionFactory);
-               activeMQSslConnectionFactory.setBrokerURL(brokerURL);
-               UserCredentialsConnectionFactoryAdapter uccfa = new UserCredentialsConnectionFactoryAdapter();
-               uccfa.setTargetConnectionFactory(activeMQSslConnectionFactory);
-               cachingConnectionFactory = new CachingConnectionFactory();
-               cachingConnectionFactory.setTargetConnectionFactory(uccfa);
-               cachingConnectionFactory.setCacheConsumers(false);
-
-               initConnectionFactoryCredentials(uccfa);
-               cachingConnectionFactory.initConnection();
-               log.info("Connected to " + brokerURL);
-               uccfa.setUsername(null);
-               uccfa.setPassword(null);
-
-       }
-
-       protected void initConnectionFactoryCredentials(
-                       final UserCredentialsConnectionFactoryAdapter uccfa) {
-               if (authenticationMode == null)
-                       authenticationMode = AUTHMODE_DEFAULT;
-
-               if (AUTHMODE_OS.equals(authenticationMode)) {
-                       // if (false) {
-                       // // Cache previous value of login conf location
-                       // String oldLoginConfLocation = System
-                       // .getProperty(LOGIN_CONFIG_PROPERTY);
-                       // // Find OS family
-                       // String osName = System.getProperty("os.name");
-                       // final String auth;
-                       // if (osName.startsWith("Windows"))
-                       // auth = "Windows";
-                       // else if (osName.startsWith("SunOS")
-                       // || osName.startsWith("Solaris"))
-                       // auth = "Solaris";
-                       // else
-                       // auth = "Unix";
-                       //
-                       // Subject subject;
-                       // // see http://old.nabble.com/osgi-and-jaas-td23485885.html
-                       // ClassLoader ccl = Thread.currentThread()
-                       // .getContextClassLoader();
-                       // try {
-                       // Thread.currentThread().setContextClassLoader(
-                       // getClass().getClassLoader());
-                       // URL url = getClass().getResource(
-                       // "/org/argeo/security/activemq/osLogin.conf");
-                       //
-                       // System.setProperty(LOGIN_CONFIG_PROPERTY, url.toString());
-                       // LoginContext lc = new LoginContext(auth);
-                       // lc.login();
-                       // subject = lc.getSubject();
-                       // } catch (LoginException le) {
-                       // throw new ArgeoException("OS authentication failed", le);
-                       // } finally {
-                       // if (oldLoginConfLocation != null)
-                       // System.setProperty(LOGIN_CONFIG_PROPERTY,
-                       // oldLoginConfLocation);
-                       // Thread.currentThread().setContextClassLoader(ccl);
-                       // }
-                       // // Extract user name
-                       // String osUsername = null;
-                       // for (Principal principal : subject.getPrincipals()) {
-                       // String className = principal.getClass().getName();
-                       // if ("Unix".equals(auth)
-                       // && "com.sun.security.auth.UnixPrincipal"
-                       // .equals(className))
-                       // osUsername = principal.getName();
-                       // else if ("Windows".equals(auth)
-                       // && "com.sun.security.auth.NTUserPrincipal"
-                       // .equals(className))
-                       // osUsername = principal.getName();
-                       // else if ("Solaris".equals(auth)
-                       // && "com.sun.security.auth.SolarisPrincipal"
-                       // .equals(className))
-                       // osUsername = principal.getName();
-                       // }
-                       //
-                       // if (osUsername == null)
-                       // throw new ArgeoException("Could not find OS user name");
-                       // }
-
-                       uccfa.setUsername(System.getProperty("user.name"));
-                       uccfa.setPassword(null);
-
-               } else if (AUTHMODE_UI.equals(authenticationMode)) {
-                       try {
-                               UIManager.setLookAndFeel(new MetalLookAndFeel());
-                       } catch (UnsupportedLookAndFeelException e) {
-                               throw new ArgeoException("Cannot load look and feel", e);
-                       }
-                       UIManager.put("ClassLoader", getClass().getClassLoader());
-                       UserPasswordDialog dialog = new UserPasswordDialog() {
-                               private static final long serialVersionUID = -891646559691412088L;
-
-                               protected void useCredentials(String username, char[] password) {
-                                       uccfa.setUsername(username);
-                                       uccfa.setPassword(new String(password));
-                               }
-                       };
-                       dialog.setVisible(true);
-               } else {
-                       throw new ArgeoException("Authentication mode '"
-                                       + authenticationMode + "' is not supported");
-               }
-
-       }
-
-       protected void prepareActiveMqSslConnectionFactory(
-                       ActiveMQSslConnectionFactory connectionFactory) {
-               try {
-                       KeyStore keyStoreKs = KeyStore.getInstance(keyStoreType);
-
-                       InputStream keyInput = keyStore.getInputStream();
-                       keyStoreKs.load(keyInput,
-                                       keyStorePassword != null ? keyStorePassword.toCharArray()
-                                                       : null);
-                       keyInput.close();
-
-                       TrustManagerFactory tmf = TrustManagerFactory
-                                       .getInstance(TrustManagerFactory.getDefaultAlgorithm());
-                       tmf.init(keyStoreKs);
-
-                       KeyManagerFactory keyManagerFactory = KeyManagerFactory
-                                       .getInstance(KeyManagerFactory.getDefaultAlgorithm());
-                       keyManagerFactory.init(keyStoreKs, keyStorePassword.toCharArray());
-
-                       connectionFactory.setKeyAndTrustManagers(keyManagerFactory
-                                       .getKeyManagers(), tmf.getTrustManagers(),
-                                       new SecureRandom());
-               } catch (Exception e) {
-                       throw new ArgeoException(
-                                       "Cannot initialize JMS connection factory", e);
-               }
-
-       }
-
-       public void destroy() throws Exception {
-               if (cachingConnectionFactory != null)
-                       cachingConnectionFactory.destroy();
-       }
-
-       public void setKeyStorePassword(String keyStorePassword) {
-               this.keyStorePassword = keyStorePassword;
-       }
-
-       public void setKeyStore(Resource keyStore) {
-               this.keyStore = keyStore;
-       }
-
-       public void setKeyStoreType(String keyStoreType) {
-               this.keyStoreType = keyStoreType;
-       }
-
-       public void setBrokerURL(String brokerUrl) {
-               this.brokerURL = brokerUrl;
-       }
-
-       public void setAuthenticationMode(String authenticationMode) {
-               this.authenticationMode = authenticationMode;
-       }
-
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/UserPasswordDialog.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/UserPasswordDialog.java
deleted file mode 100644 (file)
index 7e76f87..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.core;
-
-import java.awt.Container;
-import java.awt.GridLayout;
-import java.awt.Panel;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.Arrays;
-
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JPasswordField;
-import javax.swing.JTextField;
-
-public class UserPasswordDialog extends JDialog implements ActionListener {
-       private static final long serialVersionUID = -9052993072210981198L;
-       private static String OK = "ok";
-
-       private JTextField username = new JTextField("", 10);
-       private JPasswordField password = new JPasswordField("", 10);
-
-       private JButton okButton;
-       private JButton cancelButton;
-
-       public UserPasswordDialog() {
-               setTitle("Credentials");
-               setModal(true);
-               setLocationRelativeTo(null);
-               setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
-
-               JPanel p1 = new JPanel(new GridLayout(2, 2, 3, 3));
-               p1.add(new JLabel("User"));
-               p1.add(username);
-               p1.add(new JLabel("Password"));
-               password.setActionCommand(OK);
-               password.addActionListener(this);
-               p1.add(password);
-               add("Center", p1);
-
-               Panel p2 = new Panel();
-               okButton = addButton(p2, "OK");
-               okButton.setActionCommand(OK);
-               cancelButton = addButton(p2, "Cancel");
-               add("South", p2);
-               setSize(240, 120);
-
-               pack();
-       }
-
-       /** To be overridden */
-       protected void useCredentials(String username, char[] password) {
-               // does nothing
-       }
-
-       private JButton addButton(Container c, String name) {
-               JButton button = new JButton(name);
-               button.addActionListener(this);
-               c.add(button);
-               return button;
-       }
-
-       public final void actionPerformed(ActionEvent evt) {
-               Object source = evt.getSource();
-               if (source == okButton || evt.getActionCommand().equals(OK)) {
-                       char[] p = password.getPassword();
-                       useCredentials(username.getText(), p);
-                       Arrays.fill(p, '0');
-                       cleanUp();
-               } else if (source == cancelButton)
-                       cleanUp();
-       }
-
-       private void cleanUp() {
-               password.setText("");
-               dispose();
-       }
-
-       public static void main(String[] args) {
-               UserPasswordDialog dialog = new UserPasswordDialog() {
-                       private static final long serialVersionUID = -891646559691412088L;
-
-                       protected void useCredentials(String username, char[] password) {
-                               System.out.println(username + "/" + new String(password));
-                       }
-               };
-               dialog.setVisible(true);
-               System.out.println("After show");
-       }
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java
deleted file mode 100644 (file)
index bf4beb0..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.ldap;
-
-import static org.argeo.security.core.ArgeoUserDetails.createSimpleArgeoUser;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-import java.util.Set;
-import java.util.TreeSet;
-
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
-
-import org.argeo.security.ArgeoSecurityDao;
-import org.argeo.security.ArgeoUser;
-import org.argeo.security.SimpleArgeoUser;
-import org.argeo.security.core.ArgeoUserDetails;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.ldap.core.ContextExecutor;
-import org.springframework.ldap.core.ContextMapper;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.ldap.core.LdapTemplate;
-import org.springframework.ldap.core.support.BaseLdapPathContextSource;
-import org.springframework.security.context.SecurityContextHolder;
-import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper;
-import org.springframework.security.ldap.LdapAuthoritiesPopulator;
-import org.springframework.security.ldap.LdapUsernameToDnMapper;
-import org.springframework.security.ldap.LdapUtils;
-import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
-import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
-import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
-import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder;
-import org.springframework.security.userdetails.UserDetails;
-import org.springframework.security.userdetails.UserDetailsManager;
-import org.springframework.security.userdetails.UserDetailsService;
-import org.springframework.security.userdetails.ldap.LdapUserDetailsManager;
-import org.springframework.security.userdetails.ldap.LdapUserDetailsService;
-import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
-
-public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean {
-       // private final static Log log = LogFactory.getLog(UserDaoLdap.class);
-
-       private UserDetailsManager userDetailsManager;
-       private LdapAuthoritiesPopulator authoritiesPopulator;
-       private String userBase = "ou=People";
-       private String usernameAttributeName = "uid";
-       private String groupBase = "ou=Roles";
-       private String[] groupClasses = { "top", "groupOfNames" };
-       private String groupRoleAttributeName = "cn";
-       private String groupMemberAttributeName = "member";
-       private String defaultRole = "ROLE_USER";
-       private String rolePrefix = "ROLE_";
-
-       private final BaseLdapPathContextSource contextSource;
-       private final LdapTemplate ldapTemplate;
-
-       private LdapUsernameToDnMapper usernameMapper = null;
-
-       private UserDetailsContextMapper userDetailsMapper;
-       private LdapUserDetailsService ldapUserDetailsService;
-       private List<UserNatureMapper> userNatureMappers;
-
-       private LdapShaPasswordEncoder ldapShaPasswordEncoder = new LdapShaPasswordEncoder();
-       private Random random;
-
-       public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) {
-               this.contextSource = contextSource;
-               ldapTemplate = new LdapTemplate(this.contextSource);
-               try {
-                       random = SecureRandom.getInstance("SHA1PRNG");
-               } catch (NoSuchAlgorithmException e) {
-                       random = new Random(System.currentTimeMillis());
-               }
-       }
-
-       public void afterPropertiesSet() throws Exception {
-               if (usernameMapper == null)
-                       usernameMapper = new DefaultLdapUsernameToDnMapper(userBase,
-                                       usernameAttributeName);
-
-               if (authoritiesPopulator == null) {
-                       DefaultLdapAuthoritiesPopulator ap = new DefaultLdapAuthoritiesPopulator(
-                                       ldapTemplate.getContextSource(), groupBase);
-                       ap.setDefaultRole(defaultRole);
-                       ap.setGroupSearchFilter(groupMemberAttributeName + "={0}");
-                       authoritiesPopulator = ap;
-               }
-
-               if (userDetailsMapper == null) {
-                       ArgeoUserDetailsContextMapper audm = new ArgeoUserDetailsContextMapper();
-                       audm.setUserNatureMappers(userNatureMappers);
-                       userDetailsMapper = audm;
-               }
-
-               if (userDetailsManager == null) {
-                       LdapUserDetailsManager ludm = new LdapUserDetailsManager(
-                                       ldapTemplate.getContextSource());
-                       ludm.setGroupSearchBase(groupBase);
-                       ludm.setUserDetailsMapper(userDetailsMapper);
-                       ludm.setUsernameMapper(usernameMapper);
-                       ludm.setGroupMemberAttributeName(groupMemberAttributeName);
-                       userDetailsManager = ludm;
-               }
-
-               if (ldapUserDetailsService == null) {
-                       FilterBasedLdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch(
-                                       userBase, "(" + usernameAttributeName + "={0})",
-                                       contextSource);
-                       ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch,
-                                       authoritiesPopulator);
-                       ldapUserDetailsService.setUserDetailsMapper(userDetailsMapper);
-               }
-       }
-
-       public synchronized void createUser(ArgeoUser user) {
-               userDetailsManager.createUser(new ArgeoUserDetails(user));
-       }
-
-       public synchronized ArgeoUser getUser(String uname) {
-               SimpleArgeoUser user = createSimpleArgeoUser(getDetails(uname));
-               user.setPassword(null);
-               return user;
-       }
-
-       public synchronized ArgeoUser getUserWithPassword(String uname) {
-               return createSimpleArgeoUser(getDetails(uname));
-       }
-
-       // public ArgeoUser getCurrentUser() {
-       // ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser();
-       // if (argeoUser == null)
-       // return null;
-       // if (argeoUser.getRoles().contains(defaultRole))
-       // argeoUser.getRoles().remove(defaultRole);
-       // return argeoUser;
-       // }
-
-       @SuppressWarnings("unchecked")
-       public synchronized Set<ArgeoUser> listUsers() {
-               List<String> usernames = (List<String>) ldapTemplate.listBindings(
-                               new DistinguishedName(userBase), new ContextMapper() {
-                                       public Object mapFromContext(Object ctxArg) {
-                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
-                                               return ctx.getStringAttribute(usernameAttributeName);
-                                       }
-                               });
-
-               TreeSet<ArgeoUser> lst = new TreeSet<ArgeoUser>();
-               for (String username : usernames) {
-                       lst.add(createSimpleArgeoUser(getDetails(username)));
-               }
-               return Collections.unmodifiableSortedSet(lst);
-       }
-
-       @SuppressWarnings("unchecked")
-       public Set<String> listEditableRoles() {
-               return Collections.unmodifiableSortedSet(new TreeSet<String>(
-                               ldapTemplate.listBindings(groupBase, new ContextMapper() {
-                                       public Object mapFromContext(Object ctxArg) {
-                                               String groupName = ((DirContextAdapter) ctxArg)
-                                                               .getStringAttribute(groupRoleAttributeName);
-                                               String roleName = convertGroupToRole(groupName);
-                                               return roleName;
-                                       }
-                               })));
-       }
-
-       @SuppressWarnings("unchecked")
-       public Set<ArgeoUser> listUsersInRole(String role) {
-               return (Set<ArgeoUser>) ldapTemplate.lookup(
-                               buildGroupDn(convertRoleToGroup(role)), new ContextMapper() {
-                                       public Object mapFromContext(Object ctxArg) {
-                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
-                                               String[] userDns = ctx
-                                                               .getStringAttributes(groupMemberAttributeName);
-                                               TreeSet<ArgeoUser> set = new TreeSet<ArgeoUser>();
-                                               for (String userDn : userDns) {
-                                                       DistinguishedName dn = new DistinguishedName(userDn);
-                                                       String username = dn
-                                                                       .getValue(usernameAttributeName);
-                                                       set.add(createSimpleArgeoUser(getDetails(username)));
-                                               }
-                                               return Collections.unmodifiableSortedSet(set);
-                                       }
-                               });
-       }
-
-       public synchronized void updateUser(ArgeoUser user) {
-               ArgeoUserDetails argeoUserDetails = new ArgeoUserDetails(user);
-               userDetailsManager.updateUser(new ArgeoUserDetails(user));
-               // refresh logged in user
-               if (ArgeoUserDetails.securityContextUser().getUsername()
-                               .equals(argeoUserDetails.getUsername())) {
-                       SecurityContextHolder.getContext().setAuthentication(
-                                       new UsernamePasswordAuthenticationToken(argeoUserDetails,
-                                                       null, argeoUserDetails.getAuthorities()));
-               }
-       }
-
-       public synchronized void deleteUser(String username) {
-               userDetailsManager.deleteUser(username);
-       }
-
-       public synchronized Boolean userExists(String username) {
-               return userDetailsManager.userExists(username);
-       }
-
-       public void createRole(String role, final String superuserName) {
-               String group = convertRoleToGroup(role);
-               DistinguishedName superuserDn = (DistinguishedName) ldapTemplate
-                               .executeReadWrite(new ContextExecutor() {
-                                       public Object executeWithContext(DirContext ctx)
-                                                       throws NamingException {
-                                               return LdapUtils.getFullDn(
-                                                               usernameMapper.buildDn(superuserName), ctx);
-                                       }
-                               });
-
-               Name groupDn = buildGroupDn(group);
-               DirContextAdapter context = new DirContextAdapter();
-               context.setAttributeValues("objectClass", groupClasses);
-               context.setAttributeValue("cn", group);
-
-               // Add superuser because cannot create empty group
-               context.setAttributeValue(groupMemberAttributeName,
-                               superuserDn.toString());
-
-               ldapTemplate.bind(groupDn, context, null);
-       }
-
-       public void deleteRole(String role) {
-               String group = convertRoleToGroup(role);
-               Name dn = buildGroupDn(group);
-               ldapTemplate.unbind(dn);
-       }
-
-       public Boolean isPasswordValid(String encoded, String raw) {
-               return ldapShaPasswordEncoder.isPasswordValid(encoded, raw, null);
-       }
-
-       public String encodePassword(String raw) {
-               byte[] salt = null;
-               // TODO: check that Linux auth supports SSHA
-               // byte[] salt = new byte[16];
-               // random.nextBytes(salt);
-               return ldapShaPasswordEncoder.encodePassword(raw, salt);
-       }
-
-       protected String convertRoleToGroup(String role) {
-               String group = role;
-               if (group.startsWith(rolePrefix)) {
-                       group = group.substring(rolePrefix.length());
-                       group = group.toLowerCase();
-               }
-               return group;
-       }
-
-       public String convertGroupToRole(String groupName) {
-               groupName = groupName.toUpperCase();
-
-               return rolePrefix + groupName;
-       }
-
-       protected Name buildGroupDn(String name) {
-               return new DistinguishedName(groupRoleAttributeName + "=" + name + ","
-                               + groupBase);
-       }
-
-       public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
-               this.userDetailsManager = userDetailsManager;
-       }
-
-       public void setUserBase(String userBase) {
-               this.userBase = userBase;
-       }
-
-       public void setUsernameAttributeName(String usernameAttribute) {
-               this.usernameAttributeName = usernameAttribute;
-       }
-
-       public void setAuthoritiesPopulator(
-                       LdapAuthoritiesPopulator authoritiesPopulator) {
-               this.authoritiesPopulator = authoritiesPopulator;
-       }
-
-       protected UserDetails getDetails(String username) {
-               return userDetailsManager.loadUserByUsername(username);
-       }
-
-       public void setGroupBase(String groupBase) {
-               this.groupBase = groupBase;
-       }
-
-       public void setGroupRoleAttributeName(String groupRoleAttributeName) {
-               this.groupRoleAttributeName = groupRoleAttributeName;
-       }
-
-       public void setGroupMemberAttributeName(String groupMemberAttributeName) {
-               this.groupMemberAttributeName = groupMemberAttributeName;
-       }
-
-       public void setDefaultRole(String defaultRole) {
-               this.defaultRole = defaultRole;
-       }
-
-       public void setRolePrefix(String rolePrefix) {
-               this.rolePrefix = rolePrefix;
-       }
-
-       public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
-               this.usernameMapper = usernameMapper;
-       }
-
-       public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper) {
-               this.userDetailsMapper = userDetailsMapper;
-       }
-
-       public LdapAuthoritiesPopulator getAuthoritiesPopulator() {
-               return authoritiesPopulator;
-       }
-
-       public UserDetailsContextMapper getUserDetailsMapper() {
-               return userDetailsMapper;
-       }
-
-       public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
-               this.userNatureMappers = userNatureMappers;
-       }
-
-       public String getDefaultRole() {
-               return defaultRole;
-       }
-
-       public void setGroupClasses(String[] groupClasses) {
-               this.groupClasses = groupClasses;
-       }
-
-       public UserDetailsService getUserDetailsService() {
-               return ldapUserDetailsService;
-       }
-
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoUserDetailsContextMapper.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoUserDetailsContextMapper.java
deleted file mode 100644 (file)
index 459d5e5..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.ldap;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.argeo.security.ArgeoUser;
-import org.argeo.security.UserNature;
-import org.argeo.security.core.ArgeoUserDetails;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.security.GrantedAuthority;
-import org.springframework.security.userdetails.UserDetails;
-import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
-
-/**
- * Performs the mapping between LDAP and the user natures, using
- * {@link UserNatureMapper}.
- */
-public class ArgeoUserDetailsContextMapper implements UserDetailsContextMapper {
-       // private final static Log log = LogFactory
-       // .getLog(ArgeoUserDetailsContextMapper.class);
-
-       private List<UserNatureMapper> userNatureMappers = new ArrayList<UserNatureMapper>();
-
-       public UserDetails mapUserFromContext(DirContextOperations ctx,
-                       String username, GrantedAuthority[] authorities) {
-               byte[] arr = (byte[]) ctx.getAttributeSortedStringSet("userPassword")
-                               .first();
-               String password = new String(arr);
-
-               Map<String, UserNature> userNatures = new HashMap<String, UserNature>();
-               for (UserNatureMapper userInfoMapper : userNatureMappers) {
-                       UserNature userNature = userInfoMapper.mapUserInfoFromContext(ctx);
-                       if (userNature != null)
-                               userNatures.put(userInfoMapper.getName(), userNature);
-               }
-
-               return new ArgeoUserDetails(username,
-                               Collections.unmodifiableMap(userNatures), password, authorities);
-       }
-
-       public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
-               ctx.setAttributeValues("objectClass", new String[] { "inetOrgPerson" });
-               ctx.setAttributeValue("uid", user.getUsername());
-               ctx.setAttributeValue("userPassword", user.getPassword());
-               if (user instanceof ArgeoUser) {
-                       ArgeoUser argeoUser = (ArgeoUser) user;
-                       for (UserNature userNature : argeoUser.getUserNatures().values()) {
-                               for (UserNatureMapper userInfoMapper : userNatureMappers) {
-                                       if (userInfoMapper.supports(userNature)) {
-                                               userInfoMapper.mapUserInfoToContext(userNature, ctx);
-                                               break;// use the first mapper found and no others
-                                       }
-                               }
-                       }
-               }
-       }
-
-       public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
-               this.userNatureMappers = userNatureMappers;
-       }
-
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/UserNatureMapper.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/UserNatureMapper.java
deleted file mode 100644 (file)
index 81d9f91..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.ldap;
-
-import org.argeo.security.UserNature;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-
-/** Maps a user nature from LDAP. */
-public interface UserNatureMapper {
-       public String getName();
-
-       public void mapUserInfoToContext(UserNature userInfo, DirContextAdapter ctx);
-
-       public UserNature mapUserInfoFromContext(DirContextOperations ctx);
-
-       public Boolean supports(UserNature userInfo);
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/nature/CoworkerUserNatureMapper.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/nature/CoworkerUserNatureMapper.java
deleted file mode 100644 (file)
index 761d118..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.ldap.nature;
-
-import org.argeo.security.UserNature;
-import org.argeo.security.ldap.UserNatureMapper;
-import org.argeo.security.nature.CoworkerNature;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-
-public class CoworkerUserNatureMapper implements UserNatureMapper {
-
-       public String getName() {
-               return "coworker";
-       }
-
-       public UserNature mapUserInfoFromContext(DirContextOperations ctx) {
-               CoworkerNature nature = new CoworkerNature();
-               nature.setMobile(ctx.getStringAttribute("mobile"));
-               nature.setTelephoneNumber(ctx.getStringAttribute("telephoneNumber"));
-
-               if (nature.getMobile() == null && nature.getTelephoneNumber() == null)
-                       return null;
-               else
-                       return nature;
-       }
-
-       public void mapUserInfoToContext(UserNature userInfoArg,
-                       DirContextAdapter ctx) {
-               CoworkerNature nature = (CoworkerNature) userInfoArg;
-               if (nature.getMobile() == null || !nature.getMobile().equals("")) {
-                       ctx.setAttributeValue("mobile", nature.getMobile());
-               }
-               if (nature.getTelephoneNumber() == null
-                               || !nature.getTelephoneNumber().equals("")) {
-                       ctx.setAttributeValue("telephoneNumber",
-                                       nature.getTelephoneNumber());
-               }
-       }
-
-       public Boolean supports(UserNature userNature) {
-               return userNature instanceof CoworkerNature;
-       }
-
-}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/nature/SimpleUserNatureMapper.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/nature/SimpleUserNatureMapper.java
deleted file mode 100644 (file)
index 681c517..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.argeo.security.ldap.nature;
-
-import org.argeo.security.UserNature;
-import org.argeo.security.ldap.UserNatureMapper;
-import org.argeo.security.nature.SimpleUserNature;
-import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DirContextOperations;
-
-public class SimpleUserNatureMapper implements UserNatureMapper {
-       public String getName() {
-               return SimpleUserNature.TYPE;
-       }
-
-       public UserNature mapUserInfoFromContext(DirContextOperations ctx) {
-               SimpleUserNature nature = new SimpleUserNature();
-               nature.setLastName(ctx.getStringAttribute("sn"));
-               nature.setFirstName(ctx.getStringAttribute("givenName"));
-               nature.setEmail(ctx.getStringAttribute("mail"));
-               nature.setDescription(ctx.getStringAttribute("description"));
-               return nature;
-       }
-
-       public void mapUserInfoToContext(UserNature userInfoArg,
-                       DirContextAdapter ctx) {
-               SimpleUserNature nature = (SimpleUserNature) userInfoArg;
-               ctx.setAttributeValue("cn",
-                               nature.getFirstName() + " " + nature.getLastName());
-               ctx.setAttributeValue("sn", nature.getLastName());
-               ctx.setAttributeValue("givenName", nature.getFirstName());
-               ctx.setAttributeValue("mail", nature.getEmail());
-               if (nature.getDescription() != null
-                               && !nature.getDescription().equals("")) {
-                       ctx.setAttributeValue("description", nature.getDescription());
-               }
-       }
-
-       public Boolean supports(UserNature userNature) {
-               return userNature instanceof SimpleUserNature;
-       }
-
-}
diff --git a/security/runtime/org.argeo.security.ldap/.classpath b/security/runtime/org.argeo.security.ldap/.classpath
new file mode 100644 (file)
index 0000000..92f19d2
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+       <classpathentry kind="src" path="src/main/java"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/security/runtime/org.argeo.security.ldap/.project b/security/runtime/org.argeo.security.ldap/.project
new file mode 100644 (file)
index 0000000..942f140
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.security.ldap</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.ManifestBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.pde.SchemaBuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/security/runtime/org.argeo.security.ldap/.settings/org.eclipse.jdt.core.prefs b/security/runtime/org.argeo.security.ldap/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..740ac21
--- /dev/null
@@ -0,0 +1,8 @@
+#Wed Feb 16 11:23:43 CET 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/security/runtime/org.argeo.security.ldap/.settings/org.eclipse.pde.core.prefs b/security/runtime/org.argeo.security.ldap/.settings/org.eclipse.pde.core.prefs
new file mode 100644 (file)
index 0000000..f09f0de
--- /dev/null
@@ -0,0 +1,4 @@
+#Wed Feb 16 11:23:43 CET 2011
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/security/runtime/org.argeo.security.ldap/build.properties b/security/runtime/org.argeo.security.ldap/build.properties
new file mode 100644 (file)
index 0000000..5fc538b
--- /dev/null
@@ -0,0 +1,4 @@
+source.. = src/main/java/
+output.. = target/classes/
+bin.includes = META-INF/,\
+               .
diff --git a/security/runtime/org.argeo.security.ldap/pom.xml b/security/runtime/org.argeo.security.ldap/pom.xml
new file mode 100644 (file)
index 0000000..9c222e9
--- /dev/null
@@ -0,0 +1,69 @@
+<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.commons.security</groupId>
+               <artifactId>runtime</artifactId>
+               <version>0.2.3-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.security.ldap</artifactId>
+       <name>Commons Security LDAP</name>
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-compiler-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-source-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <version>${version.maven-bundle-plugin}</version>
+                               <configuration>
+                                       <instructions>
+                                               <Export-Package>
+                                                       org.argeo.security.ldap.*
+                                               </Export-Package>
+                                               <Import-Package>
+                                                       org.springframework.core,
+                                                       org.springframework.dao,
+                                                       *
+                                               </Import-Package>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       <dependencies>
+               <dependency>
+                       <groupId>org.argeo.commons.basic</groupId>
+                       <artifactId>org.argeo.basic.nodeps</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.argeo.commons.security</groupId>
+                       <artifactId>org.argeo.security.core</artifactId>
+                       <version>0.2.3-SNAPSHOT</version>
+               </dependency>
+
+               <!-- Spring -->
+               <dependency>
+                       <groupId>org.argeo.dep.osgi</groupId>
+                       <artifactId>org.argeo.dep.osgi.springframework.ldap</artifactId>
+               </dependency>
+
+               <!-- Logging -->
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
+               </dependency>
+
+       </dependencies>
+</project>
diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java
new file mode 100644 (file)
index 0000000..838a3cb
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.ldap;
+
+import static org.argeo.security.core.ArgeoUserDetails.createSimpleArgeoUser;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.directory.DirContext;
+
+import org.argeo.security.ArgeoSecurityDao;
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.SimpleArgeoUser;
+import org.argeo.security.core.ArgeoUserDetails;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.ldap.core.ContextExecutor;
+import org.springframework.ldap.core.ContextMapper;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.BaseLdapPathContextSource;
+import org.springframework.security.context.SecurityContextHolder;
+import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper;
+import org.springframework.security.ldap.LdapAuthoritiesPopulator;
+import org.springframework.security.ldap.LdapUsernameToDnMapper;
+import org.springframework.security.ldap.LdapUtils;
+import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
+import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
+import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
+import org.springframework.security.providers.ldap.authenticator.LdapShaPasswordEncoder;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.UserDetailsManager;
+import org.springframework.security.userdetails.UserDetailsService;
+import org.springframework.security.userdetails.ldap.LdapUserDetailsManager;
+import org.springframework.security.userdetails.ldap.LdapUserDetailsService;
+import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
+
+public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean {
+       // private final static Log log = LogFactory.getLog(UserDaoLdap.class);
+
+       private UserDetailsManager userDetailsManager;
+       private LdapAuthoritiesPopulator authoritiesPopulator;
+       private String userBase = "ou=People";
+       private String usernameAttributeName = "uid";
+       private String groupBase = "ou=Roles";
+       private String[] groupClasses = { "top", "groupOfNames" };
+       private String groupRoleAttributeName = "cn";
+       private String groupMemberAttributeName = "member";
+       private String defaultRole = "ROLE_USER";
+       private String rolePrefix = "ROLE_";
+
+       private final BaseLdapPathContextSource contextSource;
+       private final LdapTemplate ldapTemplate;
+
+       private LdapUsernameToDnMapper usernameMapper = null;
+
+       private UserDetailsContextMapper userDetailsMapper;
+       private LdapUserDetailsService ldapUserDetailsService;
+       private List<UserNatureMapper> userNatureMappers;
+
+       private LdapShaPasswordEncoder ldapShaPasswordEncoder = new LdapShaPasswordEncoder();
+       private Random random;
+
+       public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) {
+               this.contextSource = contextSource;
+               ldapTemplate = new LdapTemplate(this.contextSource);
+               try {
+                       random = SecureRandom.getInstance("SHA1PRNG");
+               } catch (NoSuchAlgorithmException e) {
+                       random = new Random(System.currentTimeMillis());
+               }
+       }
+
+       public void afterPropertiesSet() throws Exception {
+               if (usernameMapper == null)
+                       usernameMapper = new DefaultLdapUsernameToDnMapper(userBase,
+                                       usernameAttributeName);
+
+               if (authoritiesPopulator == null) {
+                       DefaultLdapAuthoritiesPopulator ap = new DefaultLdapAuthoritiesPopulator(
+                                       ldapTemplate.getContextSource(), groupBase);
+                       ap.setDefaultRole(defaultRole);
+                       ap.setGroupSearchFilter(groupMemberAttributeName + "={0}");
+                       authoritiesPopulator = ap;
+               }
+
+               if (userDetailsMapper == null) {
+                       ArgeoUserDetailsContextMapper audm = new ArgeoUserDetailsContextMapper();
+                       audm.setUserNatureMappers(userNatureMappers);
+                       userDetailsMapper = audm;
+               }
+
+               if (userDetailsManager == null) {
+                       LdapUserDetailsManager ludm = new LdapUserDetailsManager(
+                                       ldapTemplate.getContextSource());
+                       ludm.setGroupSearchBase(groupBase);
+                       ludm.setUserDetailsMapper(userDetailsMapper);
+                       ludm.setUsernameMapper(usernameMapper);
+                       ludm.setGroupMemberAttributeName(groupMemberAttributeName);
+                       userDetailsManager = ludm;
+               }
+
+               if (ldapUserDetailsService == null) {
+                       FilterBasedLdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch(
+                                       userBase, "(" + usernameAttributeName + "={0})",
+                                       contextSource);
+                       ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch,
+                                       authoritiesPopulator);
+                       ldapUserDetailsService.setUserDetailsMapper(userDetailsMapper);
+               }
+       }
+
+       public synchronized void createUser(ArgeoUser user) {
+               userDetailsManager.createUser(new ArgeoUserDetails(user));
+       }
+
+       public synchronized ArgeoUser getUser(String uname) {
+               SimpleArgeoUser user = createSimpleArgeoUser(getDetails(uname));
+               user.setPassword(null);
+               return user;
+       }
+
+       public synchronized ArgeoUser getUserWithPassword(String uname) {
+               return createSimpleArgeoUser(getDetails(uname));
+       }
+
+       // public ArgeoUser getCurrentUser() {
+       // ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser();
+       // if (argeoUser == null)
+       // return null;
+       // if (argeoUser.getRoles().contains(defaultRole))
+       // argeoUser.getRoles().remove(defaultRole);
+       // return argeoUser;
+       // }
+
+       @SuppressWarnings("unchecked")
+       public synchronized Set<ArgeoUser> listUsers() {
+               List<String> usernames = (List<String>) ldapTemplate.listBindings(
+                               new DistinguishedName(userBase), new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
+                                               return ctx.getStringAttribute(usernameAttributeName);
+                                       }
+                               });
+
+               TreeSet<ArgeoUser> lst = new TreeSet<ArgeoUser>();
+               for (String username : usernames) {
+                       lst.add(createSimpleArgeoUser(getDetails(username)));
+               }
+               return Collections.unmodifiableSortedSet(lst);
+       }
+
+       @SuppressWarnings("unchecked")
+       public Set<String> listEditableRoles() {
+               return Collections.unmodifiableSortedSet(new TreeSet<String>(
+                               ldapTemplate.listBindings(groupBase, new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               String groupName = ((DirContextAdapter) ctxArg)
+                                                               .getStringAttribute(groupRoleAttributeName);
+                                               String roleName = convertGroupToRole(groupName);
+                                               return roleName;
+                                       }
+                               })));
+       }
+
+       @SuppressWarnings("unchecked")
+       public Set<ArgeoUser> listUsersInRole(String role) {
+               return (Set<ArgeoUser>) ldapTemplate.lookup(
+                               buildGroupDn(convertRoleToGroup(role)), new ContextMapper() {
+                                       public Object mapFromContext(Object ctxArg) {
+                                               DirContextAdapter ctx = (DirContextAdapter) ctxArg;
+                                               String[] userDns = ctx
+                                                               .getStringAttributes(groupMemberAttributeName);
+                                               TreeSet<ArgeoUser> set = new TreeSet<ArgeoUser>();
+                                               for (String userDn : userDns) {
+                                                       DistinguishedName dn = new DistinguishedName(userDn);
+                                                       String username = dn
+                                                                       .getValue(usernameAttributeName);
+                                                       set.add(createSimpleArgeoUser(getDetails(username)));
+                                               }
+                                               return Collections.unmodifiableSortedSet(set);
+                                       }
+                               });
+       }
+
+       public synchronized void updateUser(ArgeoUser user) {
+               ArgeoUserDetails argeoUserDetails = new ArgeoUserDetails(user);
+               userDetailsManager.updateUser(new ArgeoUserDetails(user));
+               // refresh logged in user
+               if (ArgeoUserDetails.securityContextUser().getUsername()
+                               .equals(argeoUserDetails.getUsername())) {
+                       SecurityContextHolder.getContext().setAuthentication(
+                                       new UsernamePasswordAuthenticationToken(argeoUserDetails,
+                                                       null, argeoUserDetails.getAuthorities()));
+               }
+       }
+
+       public synchronized void deleteUser(String username) {
+               userDetailsManager.deleteUser(username);
+       }
+
+       public synchronized Boolean userExists(String username) {
+               return userDetailsManager.userExists(username);
+       }
+
+       public void createRole(String role, final String superuserName) {
+               String group = convertRoleToGroup(role);
+               DistinguishedName superuserDn = (DistinguishedName) ldapTemplate
+                               .executeReadWrite(new ContextExecutor() {
+                                       public Object executeWithContext(DirContext ctx)
+                                                       throws NamingException {
+                                               return LdapUtils.getFullDn(
+                                                               usernameMapper.buildDn(superuserName), ctx);
+                                       }
+                               });
+
+               Name groupDn = buildGroupDn(group);
+               DirContextAdapter context = new DirContextAdapter();
+               context.setAttributeValues("objectClass", groupClasses);
+               context.setAttributeValue("cn", group);
+
+               // Add superuser because cannot create empty group
+               context.setAttributeValue(groupMemberAttributeName,
+                               superuserDn.toString());
+
+               ldapTemplate.bind(groupDn, context, null);
+       }
+
+       public void deleteRole(String role) {
+               String group = convertRoleToGroup(role);
+               Name dn = buildGroupDn(group);
+               ldapTemplate.unbind(dn);
+       }
+
+       public Boolean isPasswordValid(String encoded, String raw) {
+               return ldapShaPasswordEncoder.isPasswordValid(encoded, raw, null);
+       }
+
+       public String encodePassword(String raw) {
+               byte[] salt = null;
+               // byte[] salt = new byte[16];
+               // random.nextBytes(salt);
+               return ldapShaPasswordEncoder.encodePassword(raw, salt);
+       }
+
+       protected String convertRoleToGroup(String role) {
+               String group = role;
+               if (group.startsWith(rolePrefix)) {
+                       group = group.substring(rolePrefix.length());
+                       group = group.toLowerCase();
+               }
+               return group;
+       }
+
+       public String convertGroupToRole(String groupName) {
+               groupName = groupName.toUpperCase();
+
+               return rolePrefix + groupName;
+       }
+
+       protected Name buildGroupDn(String name) {
+               return new DistinguishedName(groupRoleAttributeName + "=" + name + ","
+                               + groupBase);
+       }
+
+       public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
+               this.userDetailsManager = userDetailsManager;
+       }
+
+       public void setUserBase(String userBase) {
+               this.userBase = userBase;
+       }
+
+       public void setUsernameAttributeName(String usernameAttribute) {
+               this.usernameAttributeName = usernameAttribute;
+       }
+
+       public void setAuthoritiesPopulator(
+                       LdapAuthoritiesPopulator authoritiesPopulator) {
+               this.authoritiesPopulator = authoritiesPopulator;
+       }
+
+       protected UserDetails getDetails(String username) {
+               return userDetailsManager.loadUserByUsername(username);
+       }
+
+       public void setGroupBase(String groupBase) {
+               this.groupBase = groupBase;
+       }
+
+       public void setGroupRoleAttributeName(String groupRoleAttributeName) {
+               this.groupRoleAttributeName = groupRoleAttributeName;
+       }
+
+       public void setGroupMemberAttributeName(String groupMemberAttributeName) {
+               this.groupMemberAttributeName = groupMemberAttributeName;
+       }
+
+       public void setDefaultRole(String defaultRole) {
+               this.defaultRole = defaultRole;
+       }
+
+       public void setRolePrefix(String rolePrefix) {
+               this.rolePrefix = rolePrefix;
+       }
+
+       public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
+               this.usernameMapper = usernameMapper;
+       }
+
+       public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper) {
+               this.userDetailsMapper = userDetailsMapper;
+       }
+
+       public LdapAuthoritiesPopulator getAuthoritiesPopulator() {
+               return authoritiesPopulator;
+       }
+
+       public UserDetailsContextMapper getUserDetailsMapper() {
+               return userDetailsMapper;
+       }
+
+       public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
+               this.userNatureMappers = userNatureMappers;
+       }
+
+       public String getDefaultRole() {
+               return defaultRole;
+       }
+
+       public void setGroupClasses(String[] groupClasses) {
+               this.groupClasses = groupClasses;
+       }
+
+       public UserDetailsService getUserDetailsService() {
+               return ldapUserDetailsService;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoUserDetailsContextMapper.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoUserDetailsContextMapper.java
new file mode 100644 (file)
index 0000000..459d5e5
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.ldap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.UserNature;
+import org.argeo.security.core.ArgeoUserDetails;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
+
+/**
+ * Performs the mapping between LDAP and the user natures, using
+ * {@link UserNatureMapper}.
+ */
+public class ArgeoUserDetailsContextMapper implements UserDetailsContextMapper {
+       // private final static Log log = LogFactory
+       // .getLog(ArgeoUserDetailsContextMapper.class);
+
+       private List<UserNatureMapper> userNatureMappers = new ArrayList<UserNatureMapper>();
+
+       public UserDetails mapUserFromContext(DirContextOperations ctx,
+                       String username, GrantedAuthority[] authorities) {
+               byte[] arr = (byte[]) ctx.getAttributeSortedStringSet("userPassword")
+                               .first();
+               String password = new String(arr);
+
+               Map<String, UserNature> userNatures = new HashMap<String, UserNature>();
+               for (UserNatureMapper userInfoMapper : userNatureMappers) {
+                       UserNature userNature = userInfoMapper.mapUserInfoFromContext(ctx);
+                       if (userNature != null)
+                               userNatures.put(userInfoMapper.getName(), userNature);
+               }
+
+               return new ArgeoUserDetails(username,
+                               Collections.unmodifiableMap(userNatures), password, authorities);
+       }
+
+       public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
+               ctx.setAttributeValues("objectClass", new String[] { "inetOrgPerson" });
+               ctx.setAttributeValue("uid", user.getUsername());
+               ctx.setAttributeValue("userPassword", user.getPassword());
+               if (user instanceof ArgeoUser) {
+                       ArgeoUser argeoUser = (ArgeoUser) user;
+                       for (UserNature userNature : argeoUser.getUserNatures().values()) {
+                               for (UserNatureMapper userInfoMapper : userNatureMappers) {
+                                       if (userInfoMapper.supports(userNature)) {
+                                               userInfoMapper.mapUserInfoToContext(userNature, ctx);
+                                               break;// use the first mapper found and no others
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
+               this.userNatureMappers = userNatureMappers;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/UserNatureMapper.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/UserNatureMapper.java
new file mode 100644 (file)
index 0000000..81d9f91
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.ldap;
+
+import org.argeo.security.UserNature;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
+/** Maps a user nature from LDAP. */
+public interface UserNatureMapper {
+       public String getName();
+
+       public void mapUserInfoToContext(UserNature userInfo, DirContextAdapter ctx);
+
+       public UserNature mapUserInfoFromContext(DirContextOperations ctx);
+
+       public Boolean supports(UserNature userInfo);
+}
diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/nature/CoworkerUserNatureMapper.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/nature/CoworkerUserNatureMapper.java
new file mode 100644 (file)
index 0000000..761d118
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.ldap.nature;
+
+import org.argeo.security.UserNature;
+import org.argeo.security.ldap.UserNatureMapper;
+import org.argeo.security.nature.CoworkerNature;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
+public class CoworkerUserNatureMapper implements UserNatureMapper {
+
+       public String getName() {
+               return "coworker";
+       }
+
+       public UserNature mapUserInfoFromContext(DirContextOperations ctx) {
+               CoworkerNature nature = new CoworkerNature();
+               nature.setMobile(ctx.getStringAttribute("mobile"));
+               nature.setTelephoneNumber(ctx.getStringAttribute("telephoneNumber"));
+
+               if (nature.getMobile() == null && nature.getTelephoneNumber() == null)
+                       return null;
+               else
+                       return nature;
+       }
+
+       public void mapUserInfoToContext(UserNature userInfoArg,
+                       DirContextAdapter ctx) {
+               CoworkerNature nature = (CoworkerNature) userInfoArg;
+               if (nature.getMobile() == null || !nature.getMobile().equals("")) {
+                       ctx.setAttributeValue("mobile", nature.getMobile());
+               }
+               if (nature.getTelephoneNumber() == null
+                               || !nature.getTelephoneNumber().equals("")) {
+                       ctx.setAttributeValue("telephoneNumber",
+                                       nature.getTelephoneNumber());
+               }
+       }
+
+       public Boolean supports(UserNature userNature) {
+               return userNature instanceof CoworkerNature;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/nature/SimpleUserNatureMapper.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/nature/SimpleUserNatureMapper.java
new file mode 100644 (file)
index 0000000..681c517
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.argeo.security.ldap.nature;
+
+import org.argeo.security.UserNature;
+import org.argeo.security.ldap.UserNatureMapper;
+import org.argeo.security.nature.SimpleUserNature;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
+public class SimpleUserNatureMapper implements UserNatureMapper {
+       public String getName() {
+               return SimpleUserNature.TYPE;
+       }
+
+       public UserNature mapUserInfoFromContext(DirContextOperations ctx) {
+               SimpleUserNature nature = new SimpleUserNature();
+               nature.setLastName(ctx.getStringAttribute("sn"));
+               nature.setFirstName(ctx.getStringAttribute("givenName"));
+               nature.setEmail(ctx.getStringAttribute("mail"));
+               nature.setDescription(ctx.getStringAttribute("description"));
+               return nature;
+       }
+
+       public void mapUserInfoToContext(UserNature userInfoArg,
+                       DirContextAdapter ctx) {
+               SimpleUserNature nature = (SimpleUserNature) userInfoArg;
+               ctx.setAttributeValue("cn",
+                               nature.getFirstName() + " " + nature.getLastName());
+               ctx.setAttributeValue("sn", nature.getLastName());
+               ctx.setAttributeValue("givenName", nature.getFirstName());
+               ctx.setAttributeValue("mail", nature.getEmail());
+               if (nature.getDescription() != null
+                               && !nature.getDescription().equals("")) {
+                       ctx.setAttributeValue("description", nature.getDescription());
+               }
+       }
+
+       public Boolean supports(UserNature userNature) {
+               return userNature instanceof SimpleUserNature;
+       }
+
+}
index 0265ea32f62e5ffd8221bae070cdb1c537145b88..23e8ddd4f8f9acda409dcb2e825fe0a4db0dc8ca 100644 (file)
@@ -14,6 +14,8 @@
        <modules>
                <module>org.argeo.security.core</module>
                <module>org.argeo.security.mvc</module>
+               <module>org.argeo.security.ldap</module>
+               <module>org.argeo.security.activemq</module>
        </modules>
        <build>
                <resources>
index 3d48c8e17dae377b7f8c1798acbe57e1eeb99c38..84338825a0667f6ca7119980e8873803b2fa876b 100644 (file)
                        <groupId>org.dom4j</groupId>
                        <artifactId>com.springsource.org.dom4j</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>javax.xml.stream</groupId>
-                       <artifactId>com.springsource.javax.xml.stream</artifactId>
-               </dependency>
                <dependency>
                        <groupId>org.jdom</groupId>
                        <artifactId>com.springsource.org.jdom</artifactId>
                        <artifactId>com.springsource.org.xmlpull</artifactId>
                </dependency>
 
+               <!-- OSGi test -->
                <dependency>
                        <groupId>org.argeo.commons.osgi</groupId>
                        <artifactId>org.argeo.osgi.boot</artifactId>
                        <version>0.2.3-SNAPSHOT</version>
                        <scope>test</scope>
                </dependency>
+               <dependency>
+                       <groupId>javax.xml.stream</groupId>
+                       <artifactId>com.springsource.javax.xml.stream</artifactId>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.xmlcommons</groupId>
+                       <artifactId>com.springsource.org.apache.xmlcommons</artifactId>
+                       <scope>test</scope>
+               </dependency>
+
        </dependencies>
 </project>
\ No newline at end of file
index 58369e6e3d683a4e8dc22f6dbacda3b892fc1b70..535ef108b743af43bdc8aabc9a2bdc8ded37668e 100644 (file)
@@ -1,4 +1,5 @@
-<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">
+<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.commons.server</groupId>
@@ -10,7 +11,7 @@
        <packaging>pom</packaging>
        <name>Dep Apache Tomcat</name>
        <dependencies>
-               <!--  Commons Dep -->
+               <!-- Commons Dep -->
                <dependency>
                        <groupId>org.argeo.commons.basic</groupId>
                        <artifactId>org.argeo.basic.dep.log4j</artifactId>
                        <groupId>javax.servlet</groupId>
                        <artifactId>com.springsource.javax.servlet.jsp</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>javax.annotation</groupId>
-                       <artifactId>com.springsource.javax.annotation</artifactId>
-               </dependency>
                <dependency>
                        <groupId>javax.persistence</groupId>
                        <artifactId>com.springsource.javax.persistence</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>javax.activation</groupId>
-                       <artifactId>com.springsource.javax.activation</artifactId>
-               </dependency>
                <dependency>
                        <groupId>org.apache.geronimo.specs</groupId>
                        <artifactId>com.springsource.javax.management.j2ee</artifactId>
                        <groupId>javax.xml.rpc</groupId>
                        <artifactId>com.springsource.javax.xml.rpc</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>javax.xml.soap</groupId>
-                       <artifactId>com.springsource.javax.xml.soap</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>javax.transaction</groupId>
-                       <artifactId>com.springsource.javax.transaction</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>javax.xml.stream</groupId>
-                       <artifactId>com.springsource.javax.xml.stream</artifactId>
-               </dependency>
                <dependency>
                        <groupId>javax.servlet</groupId>
                        <artifactId>com.springsource.javax.servlet.jsp</artifactId>
                        <groupId>javax.el</groupId>
                        <artifactId>com.springsource.javax.el</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>javax.xml.ws</groupId>
-                       <artifactId>com.springsource.javax.xml.ws</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>javax.xml.bind</groupId>
-                       <artifactId>com.springsource.javax.xml.bind</artifactId>
-               </dependency>
 
                <!-- Taglibs -->
                <dependency>
                        <groupId>org.apache.el</groupId>
                        <artifactId>com.springsource.org.apache.el</artifactId>
                </dependency>
+
        </dependencies>
 </project>
\ No newline at end of file
index d07d8c19e3978b75f2e82ec589c043ea77956868..5bf5f47a9bc94f78e1a08cd6e456cc71a8c5d0db 100644 (file)
                        <groupId>javax.servlet</groupId>
                        <artifactId>com.springsource.javax.servlet</artifactId>
                </dependency>
-               <dependency>
-                       <groupId>javax.xml.stream</groupId>
-                       <artifactId>com.springsource.javax.xml.stream</artifactId>
-               </dependency>
 
                <!-- Logging -->
                <dependency>
index 8af625eec1c5bc916f9fb1fc2db805434da08676..074d07a4108b92a9fe34ca7aeb66d075ebcced24 100644 (file)
@@ -1,4 +1,5 @@
-<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">
+<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.commons.server</groupId>
                                                        org.argeo.server.jcr.*
                                                </Export-Package>
                                                <Import-Package>
-                                                       *,
+                                                       org.xml.sax;version="0.0.0",
                                                        org.springframework.security.providers.jaas;resolution:="optional",
-                                                       junit.framework;resolution:="optional"
+                                                       junit.framework;resolution:="optional",
+                                                       *
                                                </Import-Package>
                                        </instructions>
                                </configuration>
index 6bddeefd2d30c9d1cfb964aba9716e4fc3306981..87738a5cdc5dbb2b589652b502f6988136561488 100644 (file)
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
 import javax.jcr.Credentials;
 import javax.jcr.LoginException;
@@ -42,12 +43,14 @@ import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.TransientRepository;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
 import org.argeo.ArgeoException;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
 import org.springframework.context.ResourceLoaderAware;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.ResourceLoader;
+import org.xml.sax.InputSource;
 
 /**
  * Wrapper around a Jackrabbit repository which allows to configure it in Spring
@@ -59,6 +62,7 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
 
        private Resource configuration;
        private File homeDirectory;
+       private Resource variables;
 
        private Boolean inMemory = false;
 
@@ -89,13 +93,23 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
 
                RepositoryConfig config;
                InputStream in = configuration.getInputStream();
+               InputStream propsIn = null;
                try {
-                       config = RepositoryConfig.create(in,
+                       Properties vars = new Properties();
+                       if (variables != null) {
+                               propsIn = variables.getInputStream();
+                               vars.load(propsIn);
+                       }
+                       // override with system properties
+                       vars.putAll(System.getProperties());
+                       vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
                                        homeDirectory.getCanonicalPath());
+                       config = RepositoryConfig.create(new InputSource(in), vars);
                } catch (Exception e) {
                        throw new RuntimeException("Cannot read configuration", e);
                } finally {
                        IOUtils.closeQuietly(in);
+                       IOUtils.closeQuietly(propsIn);
                }
 
                if (inMemory)
@@ -217,4 +231,8 @@ public class JackrabbitContainer implements InitializingBean, DisposableBean,
                this.cndFiles = cndFiles;
        }
 
+       public void setVariables(Resource variables) {
+               this.variables = variables;
+       }
+
 }