Merging r13268 through r14040 from trunk/cdmlib into branches/cdmlib-unitils3
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / UserService.java
index 83e2fbe5e02eb1d0c9fd12d0705a8f023a813f20..8890572cbdc2cba755d360768ebbb84cd813fd26 100644 (file)
@@ -9,42 +9,53 @@
  */\r
 package eu.etaxonomy.cdm.api.service;\r
 \r
+import java.security.Permission;\r
+import java.util.ArrayList;\r
 import java.util.List;\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
-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.UserDetails;\r
-import org.springframework.security.userdetails.UsernameNotFoundException;\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
+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.api.service.pager.Pager;\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.permission.CdmPermission;\r
+import eu.etaxonomy.cdm.permission.CdmPermissionEvaluator;\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(readOnly=true)\r
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)\r
 public class UserService extends ServiceBase<User,IUserDao> implements IUserService {\r
        \r
        protected IGroupDao groupDao;\r
@@ -107,7 +118,9 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                return newAuthentication;\r
        }\r
        \r
+       @Override\r
        @Transactional(readOnly=false)\r
+       \r
        public void changePassword(String oldPassword, String newPassword) {\r
                Assert.hasText(oldPassword);\r
                Assert.hasText(newPassword);\r
@@ -129,7 +142,32 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                        throw new AccessDeniedException("Can't change password as no Authentication object found in context for current user.");\r
                }               \r
        }\r
+       \r
+       @Override\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
+       @Override\r
        @Transactional(readOnly=false)\r
        public void createUser(UserDetails user) {\r
                Assert.isInstanceOf(User.class, user);\r
@@ -143,6 +181,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                dao.save((User)user);\r
        }\r
 \r
+       @Override\r
        @Transactional(readOnly=false)\r
        public void deleteUser(String username) {\r
                Assert.hasLength(username);\r
@@ -155,6 +194,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
         userCache.removeUserFromCache(username);\r
        }\r
 \r
+       @Override\r
        @Transactional(readOnly=false)\r
        public void updateUser(UserDetails user) {\r
                Assert.isInstanceOf(User.class, user);\r
@@ -163,6 +203,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                userCache.removeUserFromCache(user.getUsername());\r
        }\r
 \r
+       @Override\r
        public boolean userExists(String username) {\r
                Assert.hasText(username);\r
                \r
@@ -170,6 +211,10 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                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
@@ -184,6 +229,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                }\r
        }\r
 \r
+       @Deprecated // use GroupService instead\r
        @Transactional(readOnly=false)\r
        public void addGroupAuthority(String groupName, GrantedAuthority authority) {\r
                Assert.hasText(groupName);\r
@@ -195,6 +241,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                }\r
        }\r
 \r
+       @Deprecated // use GroupService instead\r
        @Transactional(readOnly=false)\r
        public void addUserToGroup(String username, String groupName) {\r
                Assert.hasText(username);\r
@@ -209,13 +256,13 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                }               \r
        }\r
 \r
+       @Deprecated // use GroupService instead\r
        @Transactional(readOnly=false)\r
-       public void createGroup(String groupName, GrantedAuthority[] authorities) {\r
+       public void createGroup(String groupName, List<GrantedAuthority> authorities) {\r
                Assert.hasText(groupName);\r
                Assert.notNull(authorities);\r
                \r
-               Group group = new Group();\r
-               group.setName(groupName);\r
+               Group group = Group.NewInstance(groupName);\r
                \r
                for(GrantedAuthority authority : authorities) {\r
                        group.getGrantedAuthorities().add(authority);\r
@@ -224,6 +271,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                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
@@ -232,27 +280,30 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                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
+       @Deprecated // use GroupService instead\r
+       public List<String> findAllGroups() {\r
+               return groupDao.listNames(null,null);\r
        }\r
 \r
-       public GrantedAuthority[] findGroupAuthorities(String groupName) {\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 group.getGrantedAuthorities().toArray(new GrantedAuthority[group.getGrantedAuthorities().size()]);\r
+               return new ArrayList<GrantedAuthority>(group.getGrantedAuthorities());\r
        }\r
 \r
-       public String[] findUsersInGroup(String groupName) {\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.toArray(new String[users.size()]);\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
@@ -265,6 +316,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                }\r
        }\r
 \r
+       @Deprecated // use GroupService instead\r
        @Transactional(readOnly=false)\r
        public void removeUserFromGroup(String username, String groupName) {\r
                Assert.hasText(username);\r
@@ -279,6 +331,7 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
                }\r
        }\r
 \r
+       @Deprecated // use GroupService instead\r
        @Transactional(readOnly=false)\r
        public void renameGroup(String oldName, String newName) {\r
                Assert.hasText(oldName);\r
@@ -292,20 +345,45 @@ public class UserService extends ServiceBase<User,IUserDao> implements IUserServ
        \r
        @Transactional(readOnly=false)\r
        public UUID save(User user) {\r
-               return dao.save(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
+       @Override\r
        @Transactional(readOnly=false)\r
        public UUID saveGrantedAuthority(GrantedAuthority grantedAuthority) {\r
                return grantedAuthorityDao.save((GrantedAuthorityImpl)grantedAuthority);\r
        }\r
        \r
+       @Deprecated // use GroupService instead\r
        @Transactional(readOnly=false)\r
        public UUID saveGroup(Group group) {\r
                return groupDao.save(group);\r
        }\r
-\r
-       public <TYPE extends User> Pager<TYPE> list(Class<TYPE> type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-               return null;\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
+\r
+       \r
 } \r