remove deprecated method
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / UserService.java
index b896a91e1517f2ba5ec73ba5952f9e69642aa5aa..10ec8c2e8cfbcdfc2945cf8bc3b8ea084ef3be2b 100644 (file)
@@ -1,29 +1,31 @@
 // $Id$\r
 /**\r
  * Copyright (C) 2007 EDIT\r
- * European Distributed Institute of Taxonomy \r
+ * European Distributed Institute of Taxonomy\r
  * http://www.e-taxonomy.eu\r
- * \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.Collection;\r
+import java.util.HashMap;\r
 import java.util.List;\r
+import java.util.Map;\r
 import java.util.UUID;\r
 \r
 import org.hibernate.NonUniqueResultException;\r
+import org.hibernate.criterion.Criterion;\r
 import org.springframework.beans.factory.annotation.Autowired;\r
 import org.springframework.dao.DataAccessException;\r
 import org.springframework.dao.IncorrectResultSizeDataAccessException;\r
-\r
 import org.springframework.security.access.AccessDeniedException;\r
+import org.springframework.security.access.prepost.PreAuthorize;\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
@@ -33,324 +35,483 @@ import org.springframework.security.core.userdetails.UserDetails;
 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.api.service.exception.ReferencedObjectUndeletableException;\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
+import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
 \r
 /**\r
  * Note: All group related functionality has been refactored into a GroupService. The will be removed in a future version.\r
  */\r
 @Service\r
-@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)\r
+@Transactional(readOnly = true)\r
+// NOTE: no type level @PreAuthorize annotation for this class!\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
-       \r
-       private AuthenticationManager authenticationManager;\r
-       \r
-       private UserCache userCache = new NullUserCache();\r
-       \r
-       @Autowired(required = false)\r
-       public void setUserCache(UserCache userCache) {\r
-               Assert.notNull(userCache, "userCache cannot be null");\r
-               this.userCache = userCache;\r
-       }\r
-       \r
-       @Autowired(required = false)\r
-       public void setPasswordEncoder(PasswordEncoder passwordEncoder) {\r
-               \r
-               this.passwordEncoder = passwordEncoder;\r
-       }\r
-\r
-       @Autowired(required = false)\r
-       public void setSaltSource(SaltSource saltSource) {\r
-               this.saltSource = saltSource;\r
-       }\r
-       \r
-       @Autowired(required= false)\r
-       public void setAuthenticationManager(AuthenticationManager authenticationManager) {\r
-               this.authenticationManager = authenticationManager;\r
-       }\r
-       \r
-       @Override\r
-       @Autowired\r
-       protected void setDao(IUserDao dao) {\r
-               this.dao = dao;\r
-       }\r
-       \r
-       @Autowired\r
-       public void setGroupDao(IGroupDao groupDao) {\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
-               UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());\r
-               newAuthentication.setDetails(currentAuth.getDetails());\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
-               Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\r
-               if(authentication != null && authentication.getPrincipal() != null && authentication.getPrincipal() instanceof User) {\r
-                       User user = (User)authentication.getPrincipal();\r
-                       \r
-                       authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), oldPassword));\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
-                       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
+\r
+    protected IGroupDao groupDao;\r
+\r
+    protected IGrantedAuthorityDao grantedAuthorityDao;\r
+\r
+    private SaltSource saltSource; // = new ReflectionSaltSource();\r
+\r
+    private PasswordEncoder passwordEncoder; // = new Md5PasswordEncoder();\r
+\r
+    private AuthenticationManager authenticationManager;\r
+\r
+    private UserCache userCache = new NullUserCache();\r
+\r
+    @Autowired(required = false)\r
+    public void setUserCache(UserCache userCache) {\r
+        Assert.notNull(userCache, "userCache cannot be null");\r
+        this.userCache = userCache;\r
+    }\r
+\r
+    @Autowired(required = false)\r
+    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {\r
+\r
+        this.passwordEncoder = passwordEncoder;\r
+    }\r
+\r
+    @Autowired(required = false)\r
+    public void setSaltSource(SaltSource saltSource) {\r
+        this.saltSource = saltSource;\r
+    }\r
+\r
+    @Autowired(required= false)\r
+    public void setAuthenticationManager(AuthenticationManager authenticationManager) {\r
+        this.authenticationManager = authenticationManager;\r
+    }\r
+\r
+    @Override\r
+    @Autowired\r
+    protected void setDao(IUserDao dao) {\r
+        this.dao = dao;\r
+    }\r
+\r
+    @Autowired\r
+    public void setGroupDao(IGroupDao groupDao) {\r
+        this.groupDao = groupDao;\r
+    }\r
+\r
+    @Autowired\r
+    public void setGrantedAuthorityDao(IGrantedAuthorityDao grantedAuthorityDao) {\r
+        this.grantedAuthorityDao = grantedAuthorityDao;\r
+    }\r
+\r
+    /**\r
+     * Changes the own password of in the database of the user which is\r
+     * currently authenticated. Requires to supply the old password for security\r
+     * reasons. Refreshes the authentication in the SecurityContext after the\r
+     * password change by re-authenticating the user with the new password.\r
+     *\r
+     * @see org.springframework.security.provisioning.UserDetailsManager#changePassword(java.lang.String,\r
+     *      java.lang.String)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("isAuthenticated()")\r
+    public void changePassword(String oldPassword, String newPassword) {\r
+        Assert.hasText(oldPassword);\r
+        Assert.hasText(newPassword);\r
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();\r
+        if(authentication != null && authentication.getPrincipal() != null && authentication.getPrincipal() instanceof User) {\r
+\r
+            // get current authentication and load it from the persistence layer,\r
+            // to make sure we are modifying the instance which is\r
+            // attached to the hibernate session\r
+            User user = (User)authentication.getPrincipal();\r
+            user = dao.load(user.getUuid());\r
+\r
+            // check if old password is valid\r
+            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), oldPassword));\r
+\r
+            // make new password and set it\r
+            Object salt = this.saltSource.getSalt(user);\r
+            String password = passwordEncoder.encodePassword(newPassword, salt);\r
+            user.setPassword(password);\r
+            dao.update(user);\r
+\r
+            // authenticate the user again with the new password\r
+            UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());\r
+            newAuthentication.setDetails(authentication.getDetails());\r
+            SecurityContextHolder.getContext().setAuthentication(newAuthentication);\r
+            userCache.removeUserFromCache(user.getUsername());\r
+\r
+        } else {\r
+            throw new AccessDeniedException("Can't change password as no Authentication object found in context for current user.");\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.service.IUserService#changePasswordForUser(java.lang.String, java.lang.String)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("#username == authentication.name or hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\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 rawPassword = user.getPassword();\r
-               Object salt = this.saltSource.getSalt(user);\r
-               \r
-               String password = passwordEncoder.encodePassword(rawPassword, salt);\r
-               ((User)user).setPassword(password);\r
-               \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 = dao.findUserByUsername(username); \r
-        if(user != null) {             \r
-                   dao.delete((User)user);\r
+\r
+            String password = passwordEncoder.encodePassword(newPassword, salt);\r
+            user.setPassword(password);\r
+\r
+            dao.update(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
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.UserDetailsManager#createUser(org.springframework.security.core.userdetails.UserDetails)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void createUser(UserDetails user) {\r
+       Assert.isInstanceOf(User.class, user);\r
+\r
+        String rawPassword = user.getPassword();\r
+        Object salt = this.saltSource.getSalt(user);\r
+\r
+        String password = passwordEncoder.encodePassword(rawPassword, salt);\r
+        ((User)user).setPassword(password);\r
+\r
+        UUID userUUID = dao.save((User)user);\r
+\r
+\r
+    }\r
+\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.UserDetailsManager#deleteUser(java.lang.String)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void deleteUser(String username) {\r
+        Assert.hasLength(username);\r
+\r
+        User user = dao.findUserByUsername(username);\r
+        if(user != null) {\r
+            dao.delete(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
-               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 = 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 = dao.findUserByUsername(username);\r
-                   if(user == null) {\r
-                               throw new UsernameNotFoundException(username);\r
-                       }\r
-                   return user;\r
-               } catch(NonUniqueResultException nure) {\r
-                       throw new IncorrectResultSizeDataAccessException("More than one user found with name '" + username + "'", 1);\r
-               }\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\r
-       @Transactional(readOnly=false)\r
-       public void addGroupAuthority(String groupName, GrantedAuthority authority) {\r
-               Assert.hasText(groupName);\r
-               Assert.notNull(authority);\r
-               \r
-               Group group = groupDao.findGroupByName(groupName);\r
-               if(group.getGrantedAuthorities().add(authority)) {\r
-                       groupDao.update(group);\r
-               }\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\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 = dao.findUserByUsername(username);\r
-               \r
-               if(group.addMember(user)) {\r
-                       groupDao.update(group);\r
-                       userCache.removeUserFromCache(user.getUsername());\r
-               }               \r
-       }\r
-\r
-       @Deprecated // use GroupService instead\r
-       @Transactional(readOnly=false)\r
-       public void createGroup(String groupName, List<GrantedAuthority> authorities) {\r
-               Assert.hasText(groupName);\r
-               Assert.notNull(authorities);\r
-               \r
-               Group group = Group.NewInstance(groupName);\r
-               \r
-               for(GrantedAuthority authority : authorities) {\r
-                       group.getGrantedAuthorities().add(authority);\r
-               }\r
-               \r
-               groupDao.save(group);\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\r
-       @Transactional(readOnly=false)\r
-       public void deleteGroup(String groupName) {\r
-               Assert.hasText(groupName);\r
-               \r
-               Group group = groupDao.findGroupByName(groupName);\r
-               groupDao.delete(group);\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\r
-       public List<String> findAllGroups() {\r
-               return groupDao.listNames(null,null);\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\r
-       public List<GrantedAuthority> findGroupAuthorities(String groupName) {\r
-               Assert.hasText(groupName);\r
-               Group group = groupDao.findGroupByName(groupName);\r
-               \r
-               return new ArrayList<GrantedAuthority>(group.getGrantedAuthorities());\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\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;\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\r
-       @Transactional(readOnly=false)\r
-       public void removeGroupAuthority(String groupName,      GrantedAuthority authority) {\r
-               Assert.hasText(groupName);\r
-               Assert.notNull(authority);\r
-               \r
-               Group group = groupDao.findGroupByName(groupName);\r
-               \r
-               if(group.getGrantedAuthorities().remove(authority)) {\r
-                       groupDao.update(group);\r
-               }\r
-       }\r
-\r
-       @Deprecated // use GroupService instead\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 = dao.findUserByUsername(username);\r
-               \r
-               if(group.removeMember(user)) {\r
-                       groupDao.update(group);\r
-                       userCache.removeUserFromCache(user.getUsername());\r
-               }\r
-       }\r
-\r
-       @Transactional(readOnly=false)\r
-       public void renameGroup(String oldName, String newName) {\r
-               Assert.hasText(oldName);\r
-               Assert.hasText(newName);\r
-               \r
-               Group group = groupDao.findGroupByName(oldName);\r
-               \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
-       @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
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.UserDetailsManager#updateUser(org.springframework.security.core.userdetails.UserDetails)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void updateUser(UserDetails user) {\r
+        Assert.isInstanceOf(User.class, user);\r
+\r
+        dao.update((User)user);\r
+        userCache.removeUserFromCache(user.getUsername());\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.UserDetailsManager#userExists(java.lang.String)\r
+     */\r
+    @Override\r
+    public boolean userExists(String username) {\r
+        Assert.hasText(username);\r
+\r
+        User user = dao.findUserByUsername(username);\r
+        return user != null;\r
+    }\r
+\r
+    /**\r
+     * <b>DO NOT CALL THIS METHOD IN LONG RUNNING SESSIONS OR CONVERSATIONS\r
+     * A THROWN UsernameNotFoundException WILL RENDER THE CONVERSATION UNUSABLE</b>\r
+     *\r
+     * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)\r
+     */\r
+    // NOTE: this method must not be secured since it is being used during the\r
+    //       authentication process\r
+    @Override\r
+    public UserDetails loadUserByUsername(String username)\r
+            throws UsernameNotFoundException, DataAccessException {\r
+        Assert.hasText(username);\r
+        try {\r
+            User user = dao.findUserByUsername(username);\r
+            if(user == null) {\r
+                throw new UsernameNotFoundException(username);\r
+            }\r
+            return user;\r
+        } catch(NonUniqueResultException nure) {\r
+            throw new IncorrectResultSizeDataAccessException("More than one user found with name '" + username + "'", 1);\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#addGroupAuthority(java.lang.String, org.springframework.security.core.GrantedAuthority)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void addGroupAuthority(String groupName, GrantedAuthority authority) {\r
+        Assert.hasText(groupName);\r
+        Assert.notNull(authority);\r
+\r
+        Group group = groupDao.findGroupByName(groupName);\r
+        if(group.getGrantedAuthorities().add(authority)) {\r
+            groupDao.update(group);\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#addUserToGroup(java.lang.String, java.lang.String)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\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 = dao.findUserByUsername(username);\r
+\r
+        if(group.addMember(user)) {\r
+            groupDao.update(group);\r
+            userCache.removeUserFromCache(user.getUsername());\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#createGroup(java.lang.String, java.util.List)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void createGroup(String groupName, List<GrantedAuthority> authorities) {\r
+        Assert.hasText(groupName);\r
+        Assert.notNull(authorities);\r
+\r
+        Group group = Group.NewInstance(groupName);\r
+\r
+        for(GrantedAuthority authority : authorities) {\r
+            group.getGrantedAuthorities().add(authority);\r
+        }\r
+\r
+        groupDao.save(group);\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#deleteGroup(java.lang.String)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void deleteGroup(String groupName) {\r
+        Assert.hasText(groupName);\r
+\r
+        Group group = groupDao.findGroupByName(groupName);\r
+        groupDao.delete(group);\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#findAllGroups()\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public List<String> findAllGroups() {\r
+        return groupDao.listNames(null,null);\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#findGroupAuthorities(java.lang.String)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public List<GrantedAuthority> findGroupAuthorities(String groupName) {\r
+        Assert.hasText(groupName);\r
+        Group group = groupDao.findGroupByName(groupName);\r
+\r
+        return new ArrayList<GrantedAuthority>(group.getGrantedAuthorities());\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#findUsersInGroup(java.lang.String)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\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;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#removeGroupAuthority(java.lang.String, org.springframework.security.core.GrantedAuthority)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void removeGroupAuthority(String groupName, GrantedAuthority authority) {\r
+        Assert.hasText(groupName);\r
+        Assert.notNull(authority);\r
+\r
+        Group group = groupDao.findGroupByName(groupName);\r
+\r
+        if(group.getGrantedAuthorities().remove(authority)) {\r
+            groupDao.update(group);\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#removeUserFromGroup(java.lang.String, java.lang.String)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\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 = dao.findUserByUsername(username);\r
+\r
+        if(group.removeMember(user)) {\r
+            groupDao.update(group);\r
+            userCache.removeUserFromCache(user.getUsername());\r
+        }\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see org.springframework.security.provisioning.GroupManager#renameGroup(java.lang.String, java.lang.String)\r
+     */\r
+    @Override\r
+    @Deprecated // use GroupService instead\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public void renameGroup(String oldName, String newName) {\r
+        Assert.hasText(oldName);\r
+        Assert.hasText(newName);\r
+\r
+        Group group = groupDao.findGroupByName(oldName);\r
+\r
+        group.setName(newName);\r
+        groupDao.update(group);\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.service.ServiceBase#save(eu.etaxonomy.cdm.model.common.CdmBase)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+   // @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_RUN_AS_ADMIN') or hasRole('ROLE_USER_MANAGER')")\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
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.service.ServiceBase#update(eu.etaxonomy.cdm.model.common.CdmBase)\r
+     */\r
+    @Override\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public UUID update(User user) {\r
+        updateUser(user);\r
+        return user.getUuid();\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.service.IUserService#saveGrantedAuthority(org.springframework.security.core.GrantedAuthority)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly=false)\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public UUID saveGrantedAuthority(GrantedAuthority grantedAuthority) {\r
+        return grantedAuthorityDao.save((GrantedAuthorityImpl)grantedAuthority);\r
+    }\r
+\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.service.IUserService#listByUsername(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.List, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+     */\r
+    @Override\r
+    @Transactional(readOnly = true)\r
+    public List<User> listByUsername(String queryString,MatchMode matchmode, List<Criterion> criteria, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+         Integer numberOfResults = dao.countByUsername(queryString, matchmode, criteria);\r
+\r
+         List<User> results = new ArrayList<User>();\r
+         if(numberOfResults > 0) {\r
+                results = dao.findByUsername(queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);\r
+         }\r
+         return results;\r
+    }\r
+\r
+    /* ================================================\r
+     *  overriding methods to secure them\r
+     *  via the type level annotation @PreAuthorize\r
+     * ================================================ */\r
+\r
+    @Override\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public String delete(User persistentObject)  {\r
+        return super.delete(persistentObject);\r
+    }\r
+\r
+    @Override\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public Map<UUID, User> save(Collection<User> newInstances) {\r
+        Map<UUID, User> users = new HashMap<UUID, User>();\r
+       for (User user: newInstances){\r
+               createUser(user);\r
+               users.put(user.getUuid(), user);\r
+        }\r
+       return users;\r
+    }\r
+\r
+    @Override\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public UUID saveOrUpdate(User transientObject) {\r
+        return super.saveOrUpdate(transientObject);\r
+    }\r
+\r
+    @Override\r
+    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER_MANAGER')")\r
+    public Map<UUID, User> saveOrUpdate(Collection<User> transientInstances) {\r
+        return super.saveOrUpdate(transientInstances);\r
+    }\r
+\r
+}\r