View Javadoc

1   package com.atlassian.user.impl.hibernate;
2   
3   import com.atlassian.user.*;
4   import com.atlassian.user.impl.DuplicateEntityException;
5   import com.atlassian.user.impl.RepositoryException;
6   import com.atlassian.user.impl.hibernate.repository.HibernateRepository;
7   import com.atlassian.user.repository.RepositoryIdentifier;
8   import com.atlassian.user.search.page.DefaultPager;
9   import com.atlassian.user.search.page.Pager;
10  import com.atlassian.user.security.password.PasswordEncryptor;
11  import net.sf.hibernate.HibernateException;
12  import net.sf.hibernate.Query;
13  import net.sf.hibernate.Session;
14  import org.springframework.dao.DataAccessException;
15  import org.springframework.orm.hibernate.HibernateCallback;
16  import org.springframework.orm.hibernate.SessionFactoryUtils;
17  import org.springframework.orm.hibernate.support.HibernateDaoSupport;
18  
19  import java.util.List;
20  import java.util.Set;
21  
22  public class HibernateUserManager extends HibernateDaoSupport implements UserManager
23  {
24      private static final String USERNAME_FIELD = "username";
25      public static final String ENTITYID_FIELD = "entityid";
26  
27      private final RepositoryIdentifier identifier;
28      private final PasswordEncryptor passwordEncryptor;
29  
30      public HibernateUserManager(RepositoryIdentifier identifier, HibernateRepository repository, PasswordEncryptor passwordEncryptor)
31      {
32          this.identifier = identifier;
33          this.passwordEncryptor = passwordEncryptor;
34          setSessionFactory(repository.getSessionFactory());
35      }
36  
37      public Pager<User> getUsers() throws EntityException
38      {
39          try
40          {
41              return new DefaultPager<User>(getUsersFromHibernate());
42          }
43          catch (DataAccessException e)
44          {
45              throw new RepositoryException(e);
46          }
47      }
48  
49      public Pager<String> getUserNames() throws EntityException
50      {
51          try
52          {
53              return new DefaultPager<String>(getUsernamesFromHibernate());
54          }
55          catch (DataAccessException e)
56          {
57              throw new RepositoryException(e);
58          }
59      }
60  
61      /**
62       * @return an {@link User} if one could be found, otherwise null.
63       * @throws EntityException representing the exception which prohibited looking for or retrieving the user.
64       */
65      public User getUser(final String username) throws EntityException
66      {
67          if (username == null)
68              throw new IllegalArgumentException("Input (username) is null.");
69  
70          List result;
71  
72          try
73          {
74              result = getHibernateTemplate().executeFind(new HibernateCallback()
75              {
76                  public Object doInHibernate(Session session) throws HibernateException
77                  {
78                      Query queryObject = session.getNamedQuery("atluser.user_find");
79                      SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
80                      queryObject.setCacheable(true);
81                      if (username != null)
82                          queryObject.setParameter(USERNAME_FIELD, username);
83  
84                      return queryObject.list();
85                  }
86              });
87          }
88          catch (DataAccessException e)
89          {
90              throw new RepositoryException(e);
91          }
92  
93          return result.isEmpty() ? null : (User) result.get(0);
94      }
95  
96      public User createUser(String username) throws EntityException
97      {
98          if (username == null)
99              throw new IllegalArgumentException("Input (username) is null.");
100 
101         User existingUser = getUser(username);
102         if (existingUser != null)
103             throw new DuplicateEntityException("User with name [" + username + "] already exists in this repository (" + identifier.getName() + ")");
104 
105         User user = new DefaultHibernateUser(username);
106         getHibernateTemplate().save(user);
107 
108         return user;
109     }
110 
111     /**
112      * Encrypts the plain password, sets it on the user, and saves the user.
113      */
114     public void alterPassword(User user, String password) throws EntityException
115     {
116         DefaultHibernateUser foundUser = getUserInSession(user);
117         if (foundUser == null)
118             throw new EntityException("This repository [" + identifier.getName() + "] does not handle user [" + user.getName() + "]");
119 
120         password = passwordEncryptor.encrypt(password);
121         foundUser.setPassword(password);
122         getHibernateTemplate().saveOrUpdate(foundUser);
123     }
124 
125     public void saveUser(User user) throws EntityException
126     {
127         DefaultHibernateUser dUser = getUserInSession(user);
128    		// in spring integration with hibernate3 there is a method that does merge
129         merge((DefaultHibernateUser) user, dUser);
130         getHibernateTemplate().saveOrUpdate(dUser);
131     }
132 
133     /**
134      * Removes the specified group, if it is present.
135      *
136      * @throws EntityException if an exception which prohibited removal
137      */
138     public void removeUser(User user) throws EntityException
139     {
140         final DefaultHibernateUser foundUser = getUserInSession(user);
141         if (foundUser == null)
142             throw new IllegalArgumentException("User can not be found in this user manager: [" + user + "]");
143 
144         List<DefaultHibernateGroup> groups = getGroupsForLocalUser(foundUser);
145         if (groups != null)
146         {
147             foundUser.setGroups(null);
148 
149             for (DefaultHibernateGroup group : groups)
150             {
151                 Set members = group.getLocalMembers();
152 
153                 if (members != null)
154                     members.remove(foundUser);
155 
156                 getHibernateTemplate().saveOrUpdate(group);
157             }
158         }
159 
160         getHibernateTemplate().delete(foundUser);
161     }
162 
163     DefaultHibernateUser getUserInSession(User user) throws EntityException {
164 		validateUser(user);
165         return (DefaultHibernateUser) getUser(user.getName());
166 	}
167 
168     private void merge(DefaultHibernateUser from, DefaultHibernateUser to)
169     {
170         to.setCreated(from.getCreated());
171         to.setEmail(from.getEmail());
172         to.setFullName(from.getFullName());
173         // do not merge groups - all modifications to groups are done through
174         // the group manager methods. It is too expensive to merge groups
175         // to.setGroups(from.getGroups());
176         to.setName(from.getName());
177         to.setPassword(from.getPassword());
178     }
179 
180     private void validateUser(User user)
181     {
182         if (user == null)
183 		    throw new IllegalArgumentException("User must not be null.");
184         if (!isHandledUser(user))
185             throw new IllegalArgumentException("User is not a Hibernate entity [" + user.getClass().getName() + "]");
186     }
187 
188     private boolean isHandledUser(User user)
189     {
190         return user instanceof DefaultHibernateUser;
191     }
192 
193     public boolean isReadOnly(User user) throws EntityException
194     {
195         return false;
196     }
197 
198     /**
199      * @return a {@link com.atlassian.user.security.password.PasswordEncryptor} which handles the encrypytion of passwords for users managed by this
200      *         object.
201      * @throws UnsupportedOperationException - for {@link com.atlassian.user.UserManager} objects which do not create {@link com.atlassian.user.User} objects.
202      */
203     @SuppressWarnings({"UnusedDeclaration"})
204     public PasswordEncryptor getPasswordEncryptor(User user) throws EntityException
205     {
206         return passwordEncryptor;
207     }
208 
209 
210     /**
211      * @return the {@link com.atlassian.user.repository.RepositoryIdentifier} which is managed by this instance.
212      */
213     public RepositoryIdentifier getIdentifier()
214     {
215         return identifier;
216     }
217 
218     public RepositoryIdentifier getRepository(Entity entity) throws EntityException
219     {
220         return getUser(entity.getName()) == null ? null : identifier;
221     }
222 
223     /**
224      * Used to detemine whether an entity can be added (eg, can call {@link com.atlassian.user.UserManager#createUser(String)} or {@link com.atlassian.user.GroupManager#createGroup(String)}
225      */
226     public boolean isCreative()
227     {
228         return true;
229     }
230 
231     @SuppressWarnings({"unchecked"})
232     private List<User> getUsersFromHibernate()
233     {
234         List<User> result;
235         result = getHibernateTemplate().executeFind(new HibernateCallback()
236         {
237             public Object doInHibernate(Session session) throws HibernateException
238             {
239                 Query queryObject = session.getNamedQuery("atluser.user_findAll");
240                 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
241 
242                 return queryObject.list();
243             }
244         });
245         return result;
246     }
247 
248     @SuppressWarnings("unchecked")
249     private List<String> getUsernamesFromHibernate()
250     {
251         List result;
252         result = getHibernateTemplate().executeFind(new HibernateCallback()
253         {
254             public Object doInHibernate(Session session) throws HibernateException
255             {
256                 Query queryObject = session.getNamedQuery("atluser.user_findAllUserNames");
257                 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
258 
259                 return queryObject.list();
260             }
261         });
262         return result;
263     }
264 
265     @SuppressWarnings("unchecked")
266     private List<DefaultHibernateGroup> getGroupsForLocalUser(final DefaultHibernateUser user) throws RepositoryException
267     {
268         validateUser(user);
269 
270         try
271         {
272             return getHibernateTemplate().executeFind(new HibernateCallback()
273             {
274                 public Object doInHibernate(Session session) throws HibernateException
275                 {
276                     Query queryObject = session.getNamedQuery("atluser.group_getGroupsForUser");
277                     SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
278                     queryObject.setLong(ENTITYID_FIELD, user.getId());
279                     queryObject.setCacheable(true);
280                     return queryObject.list();
281                 }
282             });
283         }
284         catch (DataAccessException e)
285         {
286             throw new RepositoryException(e);
287         }
288     }
289 }