package org.argeo.security;
import java.util.List;
+import java.util.Map;
public interface ArgeoUser {
public String getUsername();
- public List<UserNature> getUserNatures();
+ public Map<String,UserNature> getUserNatures();
/** Implementation should refuse to add new user natures via this method. */
- public void updateUserNatures(List<UserNature> userNatures);
+ public void updateUserNatures(Map<String,UserNature> userNatures);
public List<String> getRoles();
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
public class SimpleArgeoUser implements ArgeoUser, Serializable {
private static final long serialVersionUID = 1L;
private String username;
private String password;
- private List<UserNature> userNatures = new ArrayList<UserNature>();
+ private Map<String, UserNature> userNatures = new HashMap<String, UserNature>();
private List<String> roles = new ArrayList<String>();
public SimpleArgeoUser() {
public SimpleArgeoUser(ArgeoUser argeoUser) {
username = argeoUser.getUsername();
password = argeoUser.getPassword();
- userNatures = new ArrayList<UserNature>(argeoUser.getUserNatures());
+ userNatures = new HashMap<String, UserNature>(
+ argeoUser.getUserNatures());
roles = new ArrayList<String>(argeoUser.getRoles());
}
- public List<UserNature> getUserNatures() {
+ public Map<String, UserNature> getUserNatures() {
return userNatures;
}
- public void updateUserNatures(List<UserNature> userNaturesData) {
+ public void updateUserNatures(Map<String, UserNature> userNaturesData) {
UserNature.updateUserNaturesWithCheck(userNatures, userNaturesData);
}
this.username = username;
}
- public void setUserNatures(List<UserNature> userNatures) {
+ public void setUserNatures(Map<String, UserNature> userNatures) {
this.userNatures = userNatures;
}
import java.io.Serializable;
import java.util.List;
+import java.util.Map;
import org.argeo.ArgeoException;
}
public final static void updateUserNaturesWithCheck(
- List<UserNature> userNatures, List<UserNature> userNaturesData) {
+ Map<String, UserNature> userNatures,
+ Map<String, UserNature> userNaturesData) {
if (userNatures.size() != userNaturesData.size())
throw new ArgeoException(
"It is forbidden to add or remove user natures via this method");
"Could not find a user nature of type " + type);
}
- for (int i = 0; i < userNatures.size(); i++) {
- userNatures.set(i, userNaturesData.get(i));
+ for (String key : userNatures.keySet()) {
+ userNatures.put(key, userNaturesData.get(key));
}
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
+import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
private static final long serialVersionUID = 1L;
private final static Log log = LogFactory.getLog(ArgeoUserDetails.class);
- private final List<UserNature> userNatures;
+ private final Map<String, UserNature> userNatures;
private final List<String> roles;
- public ArgeoUserDetails(String username, List<UserNature> userNatures,
+ public ArgeoUserDetails(String username, Map<String, UserNature> userNatures,
String password, GrantedAuthority[] authorities)
throws IllegalArgumentException {
super(username, password, true, true, true, true, authorities);
- this.userNatures = Collections.unmodifiableList(userNatures);
+ this.userNatures = Collections.unmodifiableMap(userNatures);
// Roles
this.roles = Collections.unmodifiableList(addAuthoritiesToRoles(
.getPassword(), rolesToAuthorities(argeoUser.getRoles()));
}
- public List<UserNature> getUserNatures() {
+ public Map<String, UserNature> getUserNatures() {
return userNatures;
}
- public void updateUserNatures(List<UserNature> userNaturesData) {
+ public void updateUserNatures(Map<String, UserNature> userNaturesData) {
UserNature.updateUserNaturesWithCheck(userNatures, userNaturesData);
}
} else {
SimpleArgeoUser argeoUser = new SimpleArgeoUser();
argeoUser.setUsername(userDetails.getUsername());
- addAuthoritiesToRoles(userDetails.getAuthorities(), argeoUser
- .getRoles());
+ addAuthoritiesToRoles(userDetails.getAuthorities(),
+ argeoUser.getRoles());
return argeoUser;
}
}
+ /** Creates an argeo user based on spring authentication */
public static ArgeoUser asArgeoUser(Authentication authentication) {
if (authentication == null)
return null;
if (authentication.getPrincipal() instanceof ArgeoUser) {
- return new SimpleArgeoUser((ArgeoUser) authentication
- .getPrincipal());
+ return new SimpleArgeoUser(
+ (ArgeoUser) authentication.getPrincipal());
} else {
SimpleArgeoUser argeoUser = new SimpleArgeoUser();
argeoUser.setUsername(authentication.getName());
- addAuthoritiesToRoles(authentication.getAuthorities(), argeoUser
- .getRoles());
+ addAuthoritiesToRoles(authentication.getAuthorities(),
+ argeoUser.getRoles());
return argeoUser;
}
}
+
+ /** The Spring security context as an argeo user */
+ public static ArgeoUser securityContextUser() {
+ Authentication authentication = SecurityContextHolder.getContext()
+ .getAuthentication();
+ ArgeoUser argeoUser = ArgeoUserDetails.asArgeoUser(authentication);
+ return argeoUser;
+ }
}
public void beforeCreate(ArgeoUser user) {
SimpleUserNature simpleUserNature = new SimpleUserNature();
simpleUserNature.setLastName("empty");// to prevent issue with sn in LDAP
- user.getUserNatures().add(simpleUserNature);
+ user.getUserNatures().put("simple",simpleUserNature);
}
public String getSuperUsername() {
}
public ArgeoUser getCurrentUser() {
- Authentication authentication = SecurityContextHolder.getContext()
- .getAuthentication();
- ArgeoUser argeoUser = ArgeoUserDetails.asArgeoUser(authentication);
+ ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser();
if (argeoUser == null)
return null;
if (argeoUser.getRoles().contains(defaultRole))
.executeReadWrite(new ContextExecutor() {
public Object executeWithContext(DirContext ctx)
throws NamingException {
- return LdapUtils.getFullDn(usernameMapper
- .buildDn(superuserName), ctx);
+ return LdapUtils.getFullDn(
+ usernameMapper.buildDn(superuserName), ctx);
}
});
context.setAttributeValue("cn", group);
// Add superuser because cannot create empty group
- context.setAttributeValue(groupMemberAttributeName, superuserDn
- .toString());
+ context.setAttributeValue(groupMemberAttributeName,
+ superuserDn.toString());
ldapTemplate.bind(groupDn, context, null);
}
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.springframework.security.userdetails.ldap.UserDetailsContextMapper;
public class ArgeoUserDetailsContextMapper implements UserDetailsContextMapper {
-// private final static Log log = LogFactory
-// .getLog(ArgeoUserDetailsContextMapper.class);
+ // private final static Log log = LogFactory
+ // .getLog(ArgeoUserDetailsContextMapper.class);
private List<UserNatureMapper> userNatureMappers = new ArrayList<UserNatureMapper>();
.first();
String password = new String(arr);
- List<UserNature> userNatures = new ArrayList<UserNature>();
+ Map<String, UserNature> userNatures = new HashMap<String, UserNature>();
for (UserNatureMapper userInfoMapper : userNatureMappers) {
UserNature userNature = userInfoMapper.mapUserInfoFromContext(ctx);
if (userNature != null)
- userNatures.add(userNature);
+ userNatures.put(userInfoMapper.getName(), userNature);
}
- return new ArgeoUserDetails(username, Collections
- .unmodifiableList(userNatures), password, authorities);
+ return new ArgeoUserDetails(username,
+ Collections.unmodifiableMap(userNatures), password, authorities);
}
public void mapUserToContext(UserDetails user, DirContextAdapter ctx) {
ctx.setAttributeValue("userPassword", user.getPassword());
if (user instanceof ArgeoUser) {
ArgeoUser argeoUser = (ArgeoUser) user;
- for (UserNature userNature : argeoUser.getUserNatures()) {
+ for (UserNature userNature : argeoUser.getUserNatures().values()) {
for (UserNatureMapper userInfoMapper : userNatureMappers) {
if (userInfoMapper.supports(userNature)) {
userInfoMapper.mapUserInfoToContext(userNature, ctx);
import org.springframework.ldap.core.DirContextOperations;
public interface UserNatureMapper {
+ public String getName();
+
public void mapUserInfoToContext(UserNature userInfo, DirContextAdapter ctx);
public UserNature mapUserInfoFromContext(DirContextOperations ctx);
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)
+ if (nature.getMobile() == null && nature.getTelephoneNumber() == null)
return null;
else
return nature;
}
if (nature.getTelephoneNumber() == null
|| !nature.getTelephoneNumber().equals("")) {
- ctx.setAttributeValue("telephoneNumber", nature
- .getTelephoneNumber());
+ ctx.setAttributeValue("telephoneNumber",
+ nature.getTelephoneNumber());
}
}
import org.springframework.ldap.core.DirContextOperations;
public class SimpleUserNatureMapper implements UserNatureMapper {
+ public String getName() {
+ return "simple";
+ }
public UserNature mapUserInfoFromContext(DirContextOperations ctx) {
SimpleUserNature nature = new SimpleUserNature();
public void mapUserInfoToContext(UserNature userInfoArg,
DirContextAdapter ctx) {
SimpleUserNature nature = (SimpleUserNature) userInfoArg;
- ctx.setAttributeValue("cn", nature.getFirstName() + " "
- + nature.getLastName());
+ ctx.setAttributeValue("cn",
+ nature.getFirstName() + " " + nature.getLastName());
ctx.setAttributeValue("sn", nature.getLastName());
ctx.setAttributeValue("givenName", nature.getFirstName());
ctx.setAttributeValue("mail", nature.getEmail());
package org.argeo.security.json;
import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
import junit.framework.TestCase;
private static Log log = LogFactory.getLog(ArgeoUserJsonTest.class);
public void testMapper() throws Exception {
- List<UserNature> natures = new ArrayList<UserNature>();
-
+ Map<String, UserNature> natures = new HashMap<String, UserNature>();
SimpleUserNature sun = new SimpleUserNature();
sun.setFirstName("Mickey");
sun.setEmail("username@domain.com");
- natures.add(sun);
-
+ natures.put("simple",sun);
CoworkerNature cwn = new CoworkerNature();
cwn.setMobile("+123456789");
- natures.add(cwn);
+ natures.put("coworker",cwn);
GrantedAuthority[] roles = { new GrantedAuthorityImpl("ROLE1"),
new GrantedAuthorityImpl("ROLE2") };
}
public void testSeriDeserialize() {
- List<UserNature> natures = new ArrayList<UserNature>();
+ Map<String, UserNature> natures = new HashMap<String, UserNature>();
JSONArray naturesJo = new JSONArray();
SimpleUserNature sun = new SimpleUserNature();
sun.setEmail("username@domain.com");
- natures.add(sun);
+ natures.put("simple",sun);
naturesJo.put(new JSONObject(sun));
CoworkerNature cwn = new CoworkerNature();
cwn.setMobile("+123456789");
- natures.add(cwn);
+ natures.put("coworker",cwn);
naturesJo.put(new JSONObject(cwn));
GrantedAuthority[] roles = { new GrantedAuthorityImpl("ROLE1"),
--- /dev/null
+package org.argeo.security.mvc;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.argeo.security.ArgeoSecurityService;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+/** Add the current argeo user as an attribute to the request. */
+public class ArgeoUserInterceptor extends HandlerInterceptorAdapter {
+ private ArgeoSecurityService securityService;
+
+ @Override
+ public boolean preHandle(HttpServletRequest request,
+ HttpServletResponse response, Object handler) throws Exception {
+ request.setAttribute("argeoUser", securityService.getSecurityDao()
+ .getCurrentUser());
+ return super.preHandle(request, response, handler);
+ }
+
+ public void setSecurityService(ArgeoSecurityService securityService) {
+ this.securityService = securityService;
+ }
+
+}
package org.argeo.security.mvc;
import java.io.Reader;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import java.util.List;
+import org.apache.commons.codec.binary.Base64;
import org.argeo.security.ArgeoSecurityService;
import org.argeo.security.ArgeoUser;
import org.argeo.security.SimpleArgeoUser;
// private final static Log log = LogFactory
// .getLog(UsersRolesController.class);
+ private String digestType = "SHA";
+
private ArgeoSecurityService securityService;
private Deserializer userDeserializer = null;
/* USER */
- @RequestMapping("/getCredentials.ria")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/getCredentials.*")
+ @ModelAttribute("user")
public ArgeoUser getCredentials() {
ArgeoUser argeoUser = securityService.getSecurityDao().getCurrentUser();
if (argeoUser == null)
return argeoUser;
}
- @RequestMapping("/getUsersList.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/getUsersList.*")
+ @ModelAttribute("users")
public List<ArgeoUser> getUsersList() {
return securityService.getSecurityDao().listUsers();
}
- @RequestMapping("/userExists.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/userExists.*")
public BooleanAnswer userExists(@RequestParam("username") String username) {
return new BooleanAnswer(securityService.getSecurityDao().userExists(
username));
}
- @RequestMapping("/createUser.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/createUser.*")
+ @ModelAttribute("user")
public ArgeoUser createUser(Reader reader) {
ArgeoUser user = userDeserializer.deserialize(reader,
SimpleArgeoUser.class);
return securityService.getSecurityDao().getUser(user.getUsername());
}
- @RequestMapping("/updateUser.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/updateUser.*")
+ @ModelAttribute("user")
public ArgeoUser updateUser(Reader reader) {
ArgeoUser user = userDeserializer.deserialize(reader,
SimpleArgeoUser.class);
return securityService.getSecurityDao().getUser(user.getUsername());
}
- @RequestMapping("/updateUserSelf.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/updateUserSelf.*")
+ @ModelAttribute("user")
/** Will only update the user natures.*/
public ArgeoUser updateUserSelf(Reader reader) {
ArgeoUser user = securityService.getSecurityDao().getCurrentUser();
return securityService.getSecurityDao().getUser(user.getUsername());
}
- @RequestMapping("/deleteUser.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/deleteUser.*")
public ServerAnswer deleteUser(@RequestParam("username") String username) {
securityService.getSecurityDao().delete(username);
return ServerAnswer.ok("User " + username + " deleted");
}
- @RequestMapping("/getUserDetails.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/getUserDetails.*")
+ @ModelAttribute("user")
public ArgeoUser getUserDetails(@RequestParam("username") String username) {
return securityService.getSecurityDao().getUser(username);
}
/* ROLE */
- @RequestMapping("/getRolesList.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/getRolesList.*")
+ @ModelAttribute("roles")
public List<String> getEditableRolesList() {
return securityService.getSecurityDao().listEditableRoles();
}
- @RequestMapping("/createRole.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/createRole.*")
public ServerAnswer createRole(@RequestParam("role") String role) {
securityService.newRole(role);
return ServerAnswer.ok("Role " + role + " created");
}
- @RequestMapping("/deleteRole.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/deleteRole.*")
public ServerAnswer deleteRole(@RequestParam("role") String role) {
securityService.getSecurityDao().deleteRole(role);
return ServerAnswer.ok("Role " + role + " deleted");
}
- @RequestMapping("/updateUserPassword.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/updateUserPassword.*")
public ServerAnswer updateUserPassword(
@RequestParam("username") String username,
@RequestParam("password") String password) {
- securityService.updateUserPassword(username, password);
+ securityService.updateUserPassword(username,
+ digestIfNecessary(password));
return ServerAnswer.ok("Password updated for user " + username);
}
- @RequestMapping("/updatePassword.security")
- @ModelAttribute(ANSWER_MODEL_KEY)
+ @RequestMapping("/updatePassword.*")
public ServerAnswer updatePassword(
@RequestParam("oldPassword") String oldPassword,
@RequestParam("password") String password) {
- securityService.updateCurrentUserPassword(oldPassword, password);
+ securityService.updateCurrentUserPassword(
+ digestIfNecessary(oldPassword), digestIfNecessary(password));
return ServerAnswer.ok("Password updated");
}
+ protected String digestIfNecessary(String str) {
+ if (!str.startsWith("{" + digestType + "}"))
+ return digest(str);
+ else
+ return str;
+ }
+
+ protected String digest(String nonEncrypted) {
+ try {
+ MessageDigest md = MessageDigest.getInstance(digestType);
+ byte[] dig = md.digest(nonEncrypted.getBytes());
+ return "{" + digestType + "}"
+ + new String(Base64.encodeBase64(dig));
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(
+ "Unexpected exception while digesting password");
+ }
+ }
+
public void setUserDeserializer(Deserializer userDeserializer) {
this.userDeserializer = userDeserializer;
}