-<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>runtime</artifactId>
+ <groupId>org.argeo.commons.security</groupId>
+ <artifactId>runtime</artifactId>
<version>0.1.1-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>com.springsource.org.antlr</artifactId>
</dependency>
+ <!-- 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>
</dependencies>
</project>
--- /dev/null
+package org.argeo.security;
+
+import java.util.List;
+
+public interface ArgeoUser {
+ public String getUsername();
+
+ public List<UserNature> getUserNatures();
+
+ public List<String> getRoles();
+}
--- /dev/null
+package org.argeo.security;
+
+public interface UserNature {
+
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+package org.argeo.security.core;
+
+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;
+ }
+
+}
--- /dev/null
+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;
+ }
+
+}
--- /dev/null
+package org.argeo.security.ldap;
+
+import org.argeo.security.UserNature;
+import org.argeo.security.core.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;
+ }
+
+}
--- /dev/null
+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);
+}