<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+ <classpathentry kind="src" path="src/test/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"/>
<artifactId>org.springframework.security</artifactId>
</dependency>
+ <!-- JSON -->
+ <dependency>
+ <groupId>org.codehaus.jackson</groupId>
+ <artifactId>com.springsource.org.codehaus.jackson.mapper</artifactId>
+ <version>1.0.0</version>
+ </dependency>
+
<dependency>
<groupId>com.springsource.json</groupId>
<artifactId>com.springsource.json</artifactId>
<artifactId>com.springsource.org.antlr</artifactId>
</dependency>
+
+
+ <!-- TEST -->
+ <dependency>
+ <groupId>org.junit</groupId>
+ <artifactId>com.springsource.junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
</project>
--- /dev/null
+package org.argeo.security;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BasicArgeoUser implements ArgeoUser, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private String username;
+ private List<UserNature> userNatures = new ArrayList<UserNature>();
+ private List<String> roles = new ArrayList<String>();
+
+ public BasicArgeoUser() {
+
+ }
+
+ public BasicArgeoUser(ArgeoUser argeoUser) {
+ username = argeoUser.getUsername();
+ userNatures = new ArrayList<UserNature>(argeoUser.getUserNatures());
+ roles = new ArrayList<String>(argeoUser.getRoles());
+ }
+
+ public List<UserNature> getUserNatures() {
+ return userNatures;
+ }
+
+ public List<String> getRoles() {
+ return roles;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public void setUserNatures(List<UserNature> userNatures) {
+ this.userNatures = userNatures;
+ }
+
+ public void setRoles(List<String> roles) {
+ this.roles = roles;
+ }
+}
package org.argeo.security;
-public interface UserNature {
+import java.util.UUID;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codehaus.jackson.annotate.JsonAnySetter;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonMethod;
+
+//@JsonAutoDetect(value = { JsonMethod.GETTER, JsonMethod.SETTER })
+public class UserNature {
+ private final static Log log = LogFactory.getLog(UserNature.class);
+
+ private String uuid = UUID.randomUUID().toString();
+ private String type;
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getType() {
+ if (type != null)
+ return type;
+ else
+ return getClass().getName();
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ @JsonAnySetter
+ public void anySetter(String key, Object obj) {
+ if (obj != null)
+ log.info("anySetter: " + key + "=" + obj + " (" + obj.getClass()
+ + "), natureType=" + type);
+ }
+
+ @JsonCreator
+ public static Object valueOf(String str) {
+ log.info("create: " + str);
+ return new UserNature();
+ }
}
public class ArgeoUserDetails extends User implements ArgeoUser {
private static final long serialVersionUID = 1L;
- private final List<UserNature> userInfos;
+ private final List<UserNature> userNatures;
private final List<String> roles;
- public ArgeoUserDetails(String username, List<UserNature> userInfos,
+ public ArgeoUserDetails(String username, List<UserNature> userNatures,
String password, GrantedAuthority[] authorities)
throws IllegalArgumentException {
super(username, password, true, true, true, true, authorities);
- this.userInfos = Collections.unmodifiableList(userInfos);
+ this.userNatures = Collections.unmodifiableList(userNatures);
// Roles
List<String> roles = new ArrayList<String>();
}
public List<UserNature> getUserNatures() {
- return userInfos;
+ return userNatures;
}
public List<String> getRoles() {
--- /dev/null
+package org.argeo.security.json;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.BasicArgeoUser;
+import org.argeo.security.UserNature;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.DeserializationContext;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.deser.CustomDeserializerFactory;
+import org.codehaus.jackson.map.deser.StdDeserializerProvider;
+
+public class ArgeoUserMapper {
+ private final static Log log = LogFactory.getLog(ArgeoUserMapper.class);
+
+ private String userNatureTypeField = "type";
+
+ private ObjectMapper mapper = new ObjectMapper();
+
+ public ArgeoUserMapper() {
+ CustomDeserializerFactory dsf = new CustomDeserializerFactory();
+ dsf.addSpecificMapping(UserNature.class, new UserNatureDeserializer());
+ StdDeserializerProvider sdp = new StdDeserializerProvider(dsf);
+ mapper.setDeserializerProvider(sdp);
+ }
+
+ public ArgeoUser parse(String content) throws JsonMappingException,
+ JsonParseException, IOException {
+
+ return mapper.readValue(content, BasicArgeoUser.class);
+ }
+
+ private class UserNatureDeserializer extends JsonDeserializer<UserNature> {
+ private JsonFactory jsonFactory = new JsonFactory();
+
+ @Override
+ public UserNature deserialize(JsonParser parser,
+ DeserializationContext dc) throws IOException,
+ JsonProcessingException {
+ try {
+ // first read as Json DOM in order to extract the type
+ // TODO: optimize with streaming API
+ JsonNode root = parser.readValueAsTree();
+ String type = root.get(userNatureTypeField).getTextValue();
+
+ // Write it back as a string
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = jsonFactory
+ .createJsonGenerator(writer);
+ generator.setCodec(mapper);
+ generator.writeTree(root);
+ String str = writer.toString();
+
+ log.info("type=" + type + ", str=" + str);
+
+ // TODO: use context classloader (in OSGi)
+ // TODO: externalize type/classes mapping
+ Class<UserNature> clss = (Class<UserNature>) Class
+ .forName(type);
+ UserNature result = mapper.readValue(str, clss);
+
+ // JavaType javaType = TypeFactory.fromClass(clss);
+ // BeanDeserializer bd = new BeanDeserializer(javaType);
+ // JsonParser parser2 = jsonFactory.createJsonParser(str);
+
+ return result;
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Cannot deserialize", e);
+ }
+ }
+
+ }
+}
--- /dev/null
+package org.argeo.security.ldap;
+
+import org.argeo.security.UserNature;
+import org.argeo.security.nature.CoworkerNature;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
+public class CoworkerUserNatureMapper implements UserNatureMapper {
+
+ public UserNature mapUserInfoFromContext(DirContextOperations ctx) {
+ CoworkerNature basicUserInfo = new CoworkerNature();
+ basicUserInfo.setDescription(ctx.getStringAttribute("description"));
+ basicUserInfo.setMobile(ctx.getStringAttribute("mobile"));
+ basicUserInfo.setTelephoneNumber(ctx
+ .getStringAttribute("telephoneNumber"));
+ return basicUserInfo;
+ }
+
+ public void mapUserInfoToContext(UserNature userInfoArg, DirContextAdapter ctx) {
+ CoworkerNature userInfo = (CoworkerNature) userInfoArg;
+ 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 CoworkerNature;
+ }
+
+}
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) {
+ public void mapUserInfoToContext(UserNature userInfoArg,
+ DirContextAdapter ctx) {
SimpleUserNature userInfo = (SimpleUserNature) userInfoArg;
- ctx.setAttributeValue("cn", userInfo.getFullName());
+ ctx.setAttributeValue("cn", userInfo.getFirstName() + " "
+ + userInfo.getLastName());
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) {
--- /dev/null
+package org.argeo.security.nature;
+
+import org.argeo.security.UserNature;
+
+public class CoworkerNature extends UserNature {
+ private String description;
+ private String mobile;
+ private String telephoneNumber;
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ 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;
+ }
+
+}
import org.argeo.security.UserNature;
-public class SimpleUserNature implements UserNature {
+public class SimpleUserNature extends UserNature {
private String email;
private String firstName;
private String lastName;
- private String description;
- private String mobile;
- private String telephoneNumber;
public String getEmail() {
return email;
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.json;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.BasicArgeoUser;
+import org.argeo.security.UserNature;
+import org.argeo.security.core.ArgeoUserDetails;
+import org.argeo.security.nature.CoworkerNature;
+import org.argeo.security.nature.SimpleUserNature;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
+
+import com.springsource.json.writer.JSONArray;
+import com.springsource.json.writer.JSONObject;
+
+public class ArgeoUserJsonTest extends TestCase {
+ private static Log log = LogFactory.getLog(ArgeoUserJsonTest.class);
+
+ public void testMapper() throws Exception {
+ List<UserNature> natures = new ArrayList<UserNature>();
+
+ SimpleUserNature sun = new SimpleUserNature();
+ sun.setFirstName("Mickey");
+ sun.setEmail("username@domain.com");
+ natures.add(sun);
+
+ CoworkerNature cwn = new CoworkerNature();
+ cwn.setMobile("+123456789");
+ natures.add(cwn);
+
+ GrantedAuthority[] roles = { new GrantedAuthorityImpl("ROLE1"),
+ new GrantedAuthorityImpl("ROLE2") };
+ ArgeoUserDetails argeoUserDetails = new ArgeoUserDetails("USER",
+ natures, "PASSWORD", roles);
+
+ BasicArgeoUser argeoUser = new BasicArgeoUser(argeoUserDetails);
+
+ StringWriter writer = new StringWriter();
+
+ JsonFactory jsonFactory = new JsonFactory();
+ JsonGenerator jsonGenerator = jsonFactory.createJsonGenerator(writer);
+ jsonGenerator.useDefaultPrettyPrinter();
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ objectMapper.writeValue(jsonGenerator, argeoUser);
+ String audJo = writer.toString();
+
+ log.info("audJo:\n" + audJo);
+
+ // BasicArgeoUser aud = objectMapper.readValue(audJo,
+ // BasicArgeoUser.class);
+
+ ArgeoUserMapper argeoUserMapper = new ArgeoUserMapper();
+ ArgeoUser argeoUserDes = argeoUserMapper.parse(audJo);
+ }
+
+ public void testSeriDeserialize() {
+ List<UserNature> natures = new ArrayList<UserNature>();
+ JSONArray naturesJo = new JSONArray();
+
+ SimpleUserNature sun = new SimpleUserNature();
+ sun.setEmail("username@domain.com");
+ natures.add(sun);
+ naturesJo.put(new JSONObject(sun));
+
+ CoworkerNature cwn = new CoworkerNature();
+ cwn.setMobile("+123456789");
+ natures.add(cwn);
+ naturesJo.put(new JSONObject(cwn));
+
+ GrantedAuthority[] roles = { new GrantedAuthorityImpl("ROLE1"),
+ new GrantedAuthorityImpl("ROLE1") };
+ ArgeoUserDetails argeoUserDetails = new ArgeoUserDetails("USER",
+ natures, "PASSWORD", roles);
+
+ JSONObject argeoUserDetailsJo = new JSONObject(argeoUserDetails);
+ argeoUserDetailsJo.put("userNatures", naturesJo);
+
+ log.info("argeoUserDetailsJo=" + argeoUserDetailsJo.toString(2));
+
+ // JSONParser jsonParser = new JSONParser();
+ // ArgeoUserDetails argeoUserDetails = JSONParser
+ }
+}