+// $Id$\r
+/**\r
+ * Copyright (C) 2007 EDIT\r
+ * European Distributed Institute of Taxonomy \r
+ * http://www.e-taxonomy.eu\r
+ * \r
+ * The contents of this file are subject to the Mozilla Public License Version 1.1\r
+ * See LICENSE.TXT at the top of this package for the full license terms.\r
+ */\r
package eu.etaxonomy.cdm.api.service;\r
\r
+import java.util.ArrayList;\r
import java.util.List;\r
+import java.util.UUID;\r
\r
import org.hibernate.NonUniqueResultException;\r
import org.springframework.beans.factory.annotation.Autowired;\r
import org.springframework.dao.DataAccessException;\r
import org.springframework.dao.IncorrectResultSizeDataAccessException;\r
-import org.springframework.security.AccessDeniedException;\r
-import org.springframework.security.Authentication;\r
-import org.springframework.security.AuthenticationManager;\r
-import org.springframework.security.GrantedAuthority;\r
-import org.springframework.security.context.SecurityContextHolder;\r
-import org.springframework.security.providers.UsernamePasswordAuthenticationToken;\r
-import org.springframework.security.providers.dao.SaltSource;\r
-import org.springframework.security.providers.dao.UserCache;\r
-import org.springframework.security.providers.dao.cache.NullUserCache;\r
-import org.springframework.security.providers.dao.salt.ReflectionSaltSource;\r
-import org.springframework.security.providers.encoding.Md5PasswordEncoder;\r
-import org.springframework.security.providers.encoding.PasswordEncoder;\r
-import org.springframework.security.userdetails.GroupManager;\r
-import org.springframework.security.userdetails.UserDetails;\r
-import org.springframework.security.userdetails.UserDetailsManager;\r
-import org.springframework.security.userdetails.UsernameNotFoundException;\r
+\r
+import org.springframework.security.access.AccessDeniedException;\r
+import org.springframework.security.authentication.AuthenticationManager;\r
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\r
+import org.springframework.security.authentication.dao.ReflectionSaltSource;\r
+import org.springframework.security.authentication.dao.SaltSource;\r
+import org.springframework.security.authentication.encoding.Md5PasswordEncoder;\r
+import org.springframework.security.authentication.encoding.PasswordEncoder;\r
+import org.springframework.security.core.Authentication;\r
+import org.springframework.security.core.GrantedAuthority;\r
+import org.springframework.security.core.context.SecurityContextHolder;\r
+import org.springframework.security.core.userdetails.UserCache;\r
+import org.springframework.security.core.userdetails.UserDetails;\r
+import org.springframework.security.core.userdetails.UsernameNotFoundException;\r
+import org.springframework.security.core.userdetails.cache.NullUserCache;\r
import org.springframework.stereotype.Service;\r
+import org.springframework.transaction.annotation.Propagation;\r
import org.springframework.transaction.annotation.Transactional;\r
import org.springframework.util.Assert;\r
\r
+import eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl;\r
import eu.etaxonomy.cdm.model.common.Group;\r
import eu.etaxonomy.cdm.model.common.User;\r
+import eu.etaxonomy.cdm.persistence.dao.common.IGrantedAuthorityDao;\r
import eu.etaxonomy.cdm.persistence.dao.common.IGroupDao;\r
import eu.etaxonomy.cdm.persistence.dao.common.IUserDao;\r
\r
@Service\r
-@Transactional\r
-public class UserService implements UserDetailsManager, GroupManager {\r
-\r
- protected IUserDao userDao;\r
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)\r
+public class UserService extends ServiceBase<User,IUserDao> implements IUserService {\r
\r
protected IGroupDao groupDao;\r
\r
+ protected IGrantedAuthorityDao grantedAuthorityDao;\r
+ \r
private SaltSource saltSource = new ReflectionSaltSource();\r
\r
private PasswordEncoder passwordEncoder = new Md5PasswordEncoder();\r
this.passwordEncoder = passwordEncoder;\r
}\r
\r
- @Autowired\r
+ @Autowired(required = false)\r
public void setSaltSource(SaltSource saltSource) {\r
this.saltSource = saltSource;\r
}\r
\r
- @Autowired\r
+ @Autowired(required= false)\r
public void setAuthenticationManager(AuthenticationManager authenticationManager) {\r
this.authenticationManager = authenticationManager;\r
}\r
\r
+ @Override\r
@Autowired\r
- public void setUserDao(IUserDao userDao) {\r
- this.userDao = userDao;\r
+ protected void setDao(IUserDao dao) {\r
+ this.dao = dao;\r
}\r
\r
@Autowired\r
this.groupDao = groupDao;\r
}\r
\r
+ @Autowired\r
+ public void setGrantedAuthorityDao(IGrantedAuthorityDao grantedAuthorityDao) {\r
+ this.grantedAuthorityDao = grantedAuthorityDao;\r
+ }\r
+ \r
+ @Transactional(readOnly=false)\r
protected Authentication createNewAuthentication(Authentication currentAuth, String newPassword) {\r
UserDetails user = loadUserByUsername(currentAuth.getName());\r
\r
return newAuthentication;\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void changePassword(String oldPassword, String newPassword) {\r
Assert.hasText(oldPassword);\r
Assert.hasText(newPassword);\r
String password = passwordEncoder.encodePassword(newPassword, salt);\r
((User)user).setPassword(password);\r
\r
- userDao.update((User)user);\r
+ dao.update((User)user);\r
SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(authentication, newPassword));\r
userCache.removeUserFromCache(user.getUsername());\r
} else {\r
throw new AccessDeniedException("Can't change password as no Authentication object found in context for current user.");\r
} \r
}\r
+ \r
+ @Transactional(readOnly=false)\r
+ public void changePasswordForUser(String username, String newPassword) {\r
+ Assert.hasText(username);\r
+ Assert.hasText(newPassword);\r
+ \r
+ try {\r
+ User user = dao.findUserByUsername(username);\r
+ if(user == null) {\r
+ throw new UsernameNotFoundException(username);\r
+ }\r
+ \r
+ Object salt = this.saltSource.getSalt(user);\r
+ \r
+ String password = passwordEncoder.encodePassword(newPassword, salt);\r
+ ((User)user).setPassword(password);\r
+ \r
+ dao.update((User)user);\r
+ userCache.removeUserFromCache(user.getUsername());\r
+ } catch(NonUniqueResultException nure) {\r
+ throw new IncorrectResultSizeDataAccessException("More than one user found with name '" + username + "'", 1);\r
+ }\r
+ }\r
\r
+ @Transactional(readOnly=false)\r
public void createUser(UserDetails user) {\r
Assert.isInstanceOf(User.class, user);\r
\r
String password = passwordEncoder.encodePassword(rawPassword, salt);\r
((User)user).setPassword(password);\r
\r
- userDao.save((User)user);\r
+ dao.save((User)user);\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void deleteUser(String username) {\r
Assert.hasLength(username);\r
\r
- User user = userDao.findUserByUsername(username); \r
+ User user = dao.findUserByUsername(username); \r
if(user != null) { \r
- userDao.delete((User)user);\r
+ dao.delete((User)user);\r
}\r
\r
userCache.removeUserFromCache(username);\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void updateUser(UserDetails user) {\r
Assert.isInstanceOf(User.class, user);\r
\r
- userDao.update((User)user);\r
+ dao.update((User)user);\r
userCache.removeUserFromCache(user.getUsername());\r
}\r
\r
public boolean userExists(String username) {\r
Assert.hasText(username);\r
\r
- User user = userDao.findUserByUsername(username);\r
+ User user = dao.findUserByUsername(username);\r
return user != null;\r
}\r
\r
+ /**\r
+ * DO NOT CALL THIS METHOD IN LONG RUNNING SESSIONS OR CONVERSATIONS\r
+ * A THROWN UsernameNotFoundException WILL RENDER THE CONVERSATION UNUSABLE\r
+ */\r
public UserDetails loadUserByUsername(String username)\r
throws UsernameNotFoundException, DataAccessException {\r
Assert.hasText(username);\r
try {\r
- User user = userDao.findUserByUsername(username);\r
+ User user = dao.findUserByUsername(username);\r
if(user == null) {\r
throw new UsernameNotFoundException(username);\r
}\r
}\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void addGroupAuthority(String groupName, GrantedAuthority authority) {\r
Assert.hasText(groupName);\r
Assert.notNull(authority);\r
}\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void addUserToGroup(String username, String groupName) {\r
Assert.hasText(username);\r
Assert.hasText(groupName);\r
\r
Group group = groupDao.findGroupByName(groupName);\r
- User user = userDao.findUserByUsername(username);\r
+ User user = dao.findUserByUsername(username);\r
\r
if(group.addMember(user)) {\r
groupDao.update(group);\r
} \r
}\r
\r
- public void createGroup(String groupName, GrantedAuthority[] authorities) {\r
+ @Transactional(readOnly=false)\r
+ public void createGroup(String groupName, List<GrantedAuthority> authorities) {\r
Assert.hasText(groupName);\r
Assert.notNull(authorities);\r
\r
groupDao.save(group);\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void deleteGroup(String groupName) {\r
Assert.hasText(groupName);\r
\r
groupDao.delete(group);\r
}\r
\r
- public String[] findAllGroups() {\r
- List<String> names = groupDao.listNames(null,null);\r
- return names.toArray(new String[names.size()]);\r
+ public List<String> findAllGroups() {\r
+ return groupDao.listNames(null,null);\r
}\r
\r
- public GrantedAuthority[] findGroupAuthorities(String groupName) {\r
+ public List<GrantedAuthority> findGroupAuthorities(String groupName) {\r
Assert.hasText(groupName);\r
Group group = groupDao.findGroupByName(groupName);\r
\r
- return group.getGrantedAuthorities().toArray(new GrantedAuthority[group.getGrantedAuthorities().size()]);\r
+ return new ArrayList<GrantedAuthority>(group.getGrantedAuthorities());\r
}\r
\r
- public String[] findUsersInGroup(String groupName) {\r
+ public List<String> findUsersInGroup(String groupName) {\r
Assert.hasText(groupName);\r
Group group = groupDao.findGroupByName(groupName);\r
\r
List<String> users = groupDao.listMembers(group, null, null);\r
\r
- return users.toArray(new String[users.size()]);\r
+ return users;\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void removeGroupAuthority(String groupName, GrantedAuthority authority) {\r
Assert.hasText(groupName);\r
Assert.notNull(authority);\r
if(group.getGrantedAuthorities().remove(authority)) {\r
groupDao.update(group);\r
}\r
- \r
}\r
\r
+ @Transactional(readOnly=false)\r
public void removeUserFromGroup(String username, String groupName) {\r
Assert.hasText(username);\r
Assert.hasText(groupName);\r
\r
Group group = groupDao.findGroupByName(groupName);\r
- User user = userDao.findUserByUsername(username);\r
+ User user = dao.findUserByUsername(username);\r
\r
if(group.removeMember(user)) {\r
groupDao.update(group);\r
}\r
}\r
\r
+ @Transactional(readOnly=false)\r
public void renameGroup(String oldName, String newName) {\r
Assert.hasText(oldName);\r
Assert.hasText(newName);\r
group.setName(newName);\r
groupDao.update(group);\r
}\r
+ \r
+ @Transactional(readOnly=false)\r
+ public UUID save(User user) {\r
+ if(user.getId() == 0 || dao.load(user.getUuid()) == null){\r
+ createUser(user);\r
+ }else{\r
+ updateUser(user);\r
+ }\r
+ return user.getUuid(); \r
+ }\r
+\r
+ @Override\r
+ public UUID update(User user) {\r
+ updateUser(user);\r
+ return user.getUuid(); \r
+ }\r
\r
-}\r
+ @Transactional(readOnly=false)\r
+ public UUID saveGrantedAuthority(GrantedAuthority grantedAuthority) {\r
+ return grantedAuthorityDao.save((GrantedAuthorityImpl)grantedAuthority);\r
+ }\r
+ \r
+ @Transactional(readOnly=false)\r
+ public UUID saveGroup(Group group) {\r
+ return groupDao.save(group);\r
+ }\r
+} \r