Introduce security core
authorMathieu Baudier <mbaudier@argeo.org>
Tue, 15 Sep 2009 13:58:25 +0000 (13:58 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Tue, 15 Sep 2009 13:58:25 +0000 (13:58 +0000)
git-svn-id: https://svn.argeo.org/commons/trunk@2918 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

12 files changed:
security/runtime/org.argeo.security.core/.classpath [new file with mode: 0644]
security/runtime/org.argeo.security.core/.project [new file with mode: 0644]
security/runtime/org.argeo.security.core/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.core/.settings/org.maven.ide.eclipse.prefs [new file with mode: 0644]
security/runtime/org.argeo.security.core/pom.xml [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserNature.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/ArgeoUserDetails.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/ArgeoUserDetailsContextMapper.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/SimpleUserNatureMapper.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/UserNatureMapper.java [new file with mode: 0644]
security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/nature/SimpleUserNature.java [new file with mode: 0644]

diff --git a/security/runtime/org.argeo.security.core/.classpath b/security/runtime/org.argeo.security.core/.classpath
new file mode 100644 (file)
index 0000000..16f01e2
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" output="target/classes" path="src/main/java"/>
+       <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.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+       <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/security/runtime/org.argeo.security.core/.project b/security/runtime/org.argeo.security.core/.project
new file mode 100644 (file)
index 0000000..578bb7b
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>org.argeo.security.core</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.maven.ide.eclipse.maven2Builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.maven.ide.eclipse.maven2Nature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>
diff --git a/security/runtime/org.argeo.security.core/.settings/org.eclipse.jdt.core.prefs b/security/runtime/org.argeo.security.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644 (file)
index 0000000..98503f2
--- /dev/null
@@ -0,0 +1,5 @@
+#Tue Sep 15 15:57:42 CEST 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/security/runtime/org.argeo.security.core/.settings/org.maven.ide.eclipse.prefs b/security/runtime/org.argeo.security.core/.settings/org.maven.ide.eclipse.prefs
new file mode 100644 (file)
index 0000000..37c4dc5
--- /dev/null
@@ -0,0 +1,9 @@
+#Tue Sep 15 15:57:41 CEST 2009
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1
diff --git a/security/runtime/org.argeo.security.core/pom.xml b/security/runtime/org.argeo.security.core/pom.xml
new file mode 100644 (file)
index 0000000..d5a031d
--- /dev/null
@@ -0,0 +1,70 @@
+<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.1.1-SNAPSHOT</version>
+               <relativePath>..</relativePath>
+       </parent>
+       <artifactId>org.argeo.security.core</artifactId>
+       <name>Commons Security Core</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.*
+                                               </Export-Package>
+                                       </instructions>
+                               </configuration>
+                       </plugin>
+               </plugins>
+       </build>
+       <dependencies>
+               <!-- Spring LDAP -->
+               <dependency>
+                       <groupId>org.springframework.ldap</groupId>
+                       <artifactId>org.springframework.ldap</artifactId>
+                       <version>1.3.0.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.springframework.ldap</groupId>
+                       <artifactId>org.springframework.ldap.core.simple</artifactId>
+                       <version>1.3.0.RELEASE</version>
+               </dependency>
+
+               <!-- Security -->
+               <dependency>
+                       <groupId>org.springframework.security</groupId>
+                       <artifactId>org.springframework.security</artifactId>
+               </dependency>
+
+               <dependency>
+                       <groupId>com.springsource.json</groupId>
+                       <artifactId>com.springsource.json</artifactId>
+                       <version>1.0.1.RELEASE</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.antlr</groupId>
+                       <artifactId>com.springsource.org.antlr</artifactId>
+               </dependency>
+
+       </dependencies>
+</project>
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java
new file mode 100644 (file)
index 0000000..5d2eea6
--- /dev/null
@@ -0,0 +1,11 @@
+package org.argeo.security;
+
+import java.util.List;
+
+public interface ArgeoUser {
+       public String getUsername();
+
+       public List<UserNature> getUserNatures();
+
+       public List<String> getRoles();
+}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserNature.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserNature.java
new file mode 100644 (file)
index 0000000..eceed39
--- /dev/null
@@ -0,0 +1,5 @@
+package org.argeo.security;
+
+public interface UserNature {
+
+}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/ArgeoUserDetails.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/core/ArgeoUserDetails.java
new file mode 100644 (file)
index 0000000..4a6882a
--- /dev/null
@@ -0,0 +1,39 @@
+package org.argeo.security.core;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.UserNature;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.userdetails.User;
+
+public class ArgeoUserDetails extends User implements ArgeoUser {
+       private static final long serialVersionUID = 1L;
+
+       private final List<UserNature> userInfos;
+       private final List<String> roles;
+
+       public ArgeoUserDetails(String username, List<UserNature> userInfos,
+                       String password, GrantedAuthority[] authorities)
+                       throws IllegalArgumentException {
+               super(username, password, true, true, true, true, authorities);
+               this.userInfos = Collections.unmodifiableList(userInfos);
+               
+               // Roles
+               List<String> roles = new ArrayList<String>();
+               for (GrantedAuthority authority : getAuthorities()) {
+                       roles.add(authority.getAuthority());
+               }
+               this.roles = Collections.unmodifiableList(roles);
+       }
+
+       public List<UserNature> getUserNatures() {
+               return userInfos;
+       }
+
+       public List<String> getRoles() {
+               return roles;
+       }
+}
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
new file mode 100644 (file)
index 0000000..25b5c6e
--- /dev/null
@@ -0,0 +1,55 @@
+package org.argeo.security.ldap;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+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;
+
+public class ArgeoUserDetailsContextMapper implements UserDetailsContextMapper {
+       private List<UserNatureMapper> userInfoMappers = new ArrayList<UserNatureMapper>();
+
+       public UserDetails mapUserFromContext(DirContextOperations ctx,
+                       String username, GrantedAuthority[] authorities) {
+               byte[] arr = (byte[]) ctx.getAttributeSortedStringSet("userPassword")
+                               .first();
+               String password = new String(arr);
+
+               List<UserNature> userInfos = new ArrayList<UserNature>();
+               for (UserNatureMapper userInfoMapper : userInfoMappers) {
+                       userInfos.add(userInfoMapper.mapUserInfoFromContext(ctx));
+               }
+
+               return new ArgeoUserDetails(username, Collections
+                               .unmodifiableList(userInfos), 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 userInfo : argeoUser.getUserNatures()) {
+                               for (UserNatureMapper userInfoMapper : userInfoMappers) {
+                                       if (userInfoMapper.supports(userInfo)) {
+                                               userInfoMapper.mapUserInfoToContext(userInfo, ctx);
+                                               break;// use the first mapper found an no others
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public void setUserInfoMappers(List<UserNatureMapper> userInfoMappers) {
+               this.userInfoMappers = userInfoMappers;
+       }
+
+}
diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/SimpleUserNatureMapper.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ldap/SimpleUserNatureMapper.java
new file mode 100644 (file)
index 0000000..aae3426
--- /dev/null
@@ -0,0 +1,45 @@
+package org.argeo.security.ldap;
+
+import org.argeo.security.UserNature;
+import org.argeo.security.nature.SimpleUserNature;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
+public class SimpleUserNatureMapper implements UserNatureMapper {
+
+       public UserNature mapUserInfoFromContext(DirContextOperations ctx) {
+               SimpleUserNature basicUserInfo = new SimpleUserNature();
+               basicUserInfo.setLastName(ctx.getStringAttribute("sn"));
+               basicUserInfo.setFirstName(ctx.getStringAttribute("givenName"));
+               basicUserInfo.setEmail(ctx.getStringAttribute("mail"));
+               basicUserInfo.setDescription(ctx.getStringAttribute("description"));
+               basicUserInfo.setMobile(ctx.getStringAttribute("mobile"));
+               basicUserInfo.setTelephoneNumber(ctx
+                               .getStringAttribute("telephoneNumber"));
+               return basicUserInfo;
+       }
+
+       public void mapUserInfoToContext(UserNature userInfoArg, DirContextAdapter ctx) {
+               SimpleUserNature userInfo = (SimpleUserNature) userInfoArg;
+               ctx.setAttributeValue("cn", userInfo.getFullName());
+               ctx.setAttributeValue("sn", userInfo.getLastName());
+               ctx.setAttributeValue("givenName", userInfo.getFirstName());
+               ctx.setAttributeValue("mail", userInfo.getEmail());
+               if (userInfo.getDescription() != null) {
+                       ctx.setAttributeValue("description", userInfo.getDescription());
+               }
+               if (userInfo.getMobile() == null || !userInfo.getMobile().equals("")) {
+                       ctx.setAttributeValue("mobile", userInfo.getMobile());
+               }
+               if (userInfo.getTelephoneNumber() == null
+                               || !userInfo.getTelephoneNumber().equals("")) {
+                       ctx.setAttributeValue("telephoneNumber", userInfo
+                                       .getTelephoneNumber());
+               }
+       }
+
+       public Boolean supports(UserNature userInfo) {
+               return userInfo instanceof SimpleUserNature;
+       }
+
+}
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
new file mode 100644 (file)
index 0000000..9b174d3
--- /dev/null
@@ -0,0 +1,13 @@
+package org.argeo.security.ldap;
+
+import org.argeo.security.UserNature;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
+public interface UserNatureMapper {
+       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/nature/SimpleUserNature.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/nature/SimpleUserNature.java
new file mode 100644 (file)
index 0000000..1aac27a
--- /dev/null
@@ -0,0 +1,65 @@
+package org.argeo.security.nature;
+
+import org.argeo.security.UserNature;
+
+public class SimpleUserNature implements UserNature {
+       private String email;
+       private String firstName;
+       private String lastName;
+       private String description;
+       private String mobile;
+       private String telephoneNumber;
+
+       public String getEmail() {
+               return email;
+       }
+
+       public void setEmail(String email) {
+               this.email = email;
+       }
+
+       public String getFirstName() {
+               return firstName;
+       }
+
+       public void setFirstName(String firstName) {
+               this.firstName = firstName;
+       }
+
+       public String getLastName() {
+               return lastName;
+       }
+
+       public void setLastName(String lastName) {
+               this.lastName = lastName;
+       }
+
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+
+       public String getFullName() {
+               return getFirstName() + " " + getLastName();
+       }
+
+       public String getMobile() {
+               return mobile;
+       }
+
+       public void setMobile(String mobile) {
+               this.mobile = mobile;
+       }
+
+       public String getTelephoneNumber() {
+               return telephoneNumber;
+       }
+
+       public void setTelephoneNumber(String telephoneNumber) {
+               this.telephoneNumber = telephoneNumber;
+       }
+
+}