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.Credential;
11 import com.atlassian.user.security.password.PasswordEncryptor;
12 import com.atlassian.user.util.Assert;
13 import net.sf.hibernate.HibernateException;
14 import net.sf.hibernate.Query;
15 import net.sf.hibernate.Session;
16 import org.springframework.dao.DataAccessException;
17 import org.springframework.orm.hibernate.HibernateCallback;
18 import org.springframework.orm.hibernate.SessionFactoryUtils;
19 import org.springframework.orm.hibernate.support.HibernateDaoSupport;
20
21 import java.util.List;
22 import java.util.Set;
23
24 public class HibernateUserManager extends HibernateDaoSupport implements UserManager
25 {
26 private static final String USERNAME_FIELD = "username";
27 public static final String ENTITYID_FIELD = "entityid";
28
29 private final RepositoryIdentifier identifier;
30 private final PasswordEncryptor passwordEncryptor;
31
32 public HibernateUserManager(RepositoryIdentifier identifier, HibernateRepository repository, PasswordEncryptor passwordEncryptor)
33 {
34 this.identifier = identifier;
35 this.passwordEncryptor = passwordEncryptor;
36 setSessionFactory(repository.getSessionFactory());
37 }
38
39 public Pager<User> getUsers() throws EntityException
40 {
41 try
42 {
43 return new DefaultPager<User>(getUsersFromHibernate());
44 }
45 catch (DataAccessException e)
46 {
47 throw new RepositoryException(e);
48 }
49 }
50
51 public Pager<String> getUserNames() throws EntityException
52 {
53 try
54 {
55 return new DefaultPager<String>(getUsernamesFromHibernate());
56 }
57 catch (DataAccessException e)
58 {
59 throw new RepositoryException(e);
60 }
61 }
62
63
64
65
66
67 public User getUser(final String username) throws EntityException
68 {
69 return internalGetUser(username);
70 }
71
72 public User createUser(String username) throws EntityException
73 {
74 validateNewUserName(username);
75
76 User user = new DefaultHibernateUser(username);
77 getHibernateTemplate().save(user);
78
79 return user;
80 }
81
82 public User createUser(User userTemplate, Credential credential) throws EntityException
83 {
84 validateNewUserName(userTemplate.getName());
85
86 DefaultHibernateUser user = new DefaultHibernateUser(userTemplate.getName());
87 user.setFullName(userTemplate.getFullName());
88 user.setEmail(userTemplate.getEmail());
89 user.setPassword(passwordEncryptor.getEncryptedValue(credential));
90 getHibernateTemplate().save(user);
91
92 return user;
93 }
94
95 private void validateNewUserName(String name) throws EntityException
96 {
97 if (name == null)
98 throw new IllegalArgumentException("Username cannot be null.");
99
100 User existingUser = getUser(name);
101 if (existingUser != null)
102 throw new DuplicateEntityException("User with name [" + name + "] already exists in this repository (" + identifier.getName() + ")");
103 }
104
105
106
107
108 public void alterPassword(User user, String password) throws EntityException
109 {
110 DefaultHibernateUser foundUser = internalGetUser(user.getName());
111 if (foundUser == null)
112 throw new EntityException("This repository [" + identifier.getName() + "] does not handle user [" + user.getName() + "]");
113
114 String encryptedPassword = passwordEncryptor.encrypt(password);
115 foundUser.setPassword(encryptedPassword);
116 getHibernateTemplate().saveOrUpdate(foundUser);
117 }
118
119 public void saveUser(User user) throws EntityException
120 {
121 Assert.notNull(user, "User must not be null");
122 DefaultHibernateUser persistedUser = internalGetUser(user.getName());
123 if (persistedUser == null)
124 throw new EntityException("This repository [" + identifier + "] does not handle user [" + user.getName() + "]");
125
126 persistedUser.setFullName(user.getFullName());
127 persistedUser.setEmail(user.getEmail());
128 getHibernateTemplate().saveOrUpdate(persistedUser);
129 }
130
131
132
133
134
135
136 public void removeUser(User user) throws EntityException
137 {
138 final DefaultHibernateUser foundUser = internalGetUser(user.getName());
139 if (foundUser == null)
140 throw new IllegalArgumentException("User can not be found in this user manager: [" + user + "]");
141
142 List<DefaultHibernateGroup> groups = getGroupsForLocalUser(foundUser);
143 if (groups != null)
144 {
145 foundUser.setGroups(null);
146
147 for (DefaultHibernateGroup group : groups)
148 {
149 Set members = group.getLocalMembers();
150
151 if (members != null)
152 members.remove(foundUser);
153
154 getHibernateTemplate().saveOrUpdate(group);
155 }
156 }
157
158 getHibernateTemplate().delete(foundUser);
159 }
160
161 @SuppressWarnings({"unchecked"})
162 private DefaultHibernateUser internalGetUser(final String username) throws RepositoryException
163 {
164 Assert.notNull(username, "User must not be null");
165 List<DefaultHibernateUser> result;
166 try
167 {
168 result = getHibernateTemplate().executeFind(new HibernateCallback()
169 {
170 public Object doInHibernate(Session session) throws HibernateException
171 {
172 Query query = session.getNamedQuery("atluser.user_find");
173 SessionFactoryUtils.applyTransactionTimeout(query, getSessionFactory());
174 query.setCacheable(true);
175 query.setParameter(USERNAME_FIELD, username);
176 return query.list();
177 }
178 });
179 }
180 catch (DataAccessException e)
181 {
182 throw new RepositoryException(e);
183 }
184
185 return result.isEmpty() ? null : result.get(0);
186 }
187
188 public boolean isReadOnly(User user) throws EntityException
189 {
190 return false;
191 }
192
193
194
195
196
197
198 @SuppressWarnings({"UnusedDeclaration"})
199 public PasswordEncryptor getPasswordEncryptor(User user) throws EntityException
200 {
201 return passwordEncryptor;
202 }
203
204
205
206
207
208 public RepositoryIdentifier getIdentifier()
209 {
210 return identifier;
211 }
212
213 public RepositoryIdentifier getRepository(Entity entity) throws EntityException
214 {
215 return getUser(entity.getName()) == null ? null : identifier;
216 }
217
218
219
220
221 public boolean isCreative()
222 {
223 return true;
224 }
225
226 @SuppressWarnings({"unchecked"})
227 private List<User> getUsersFromHibernate()
228 {
229 List<User> result;
230 result = getHibernateTemplate().executeFind(new HibernateCallback()
231 {
232 public Object doInHibernate(Session session) throws HibernateException
233 {
234 Query queryObject = session.getNamedQuery("atluser.user_findAll");
235 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
236
237 return queryObject.list();
238 }
239 });
240 return result;
241 }
242
243 @SuppressWarnings("unchecked")
244 private List<String> getUsernamesFromHibernate()
245 {
246 List result;
247 result = getHibernateTemplate().executeFind(new HibernateCallback()
248 {
249 public Object doInHibernate(Session session) throws HibernateException
250 {
251 Query queryObject = session.getNamedQuery("atluser.user_findAllUserNames");
252 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
253
254 return queryObject.list();
255 }
256 });
257 return result;
258 }
259
260 @SuppressWarnings("unchecked")
261 private List<DefaultHibernateGroup> getGroupsForLocalUser(final DefaultHibernateUser user) throws RepositoryException
262 {
263 Assert.notNull(user, "User must not be null");
264
265 try
266 {
267 return getHibernateTemplate().executeFind(new HibernateCallback()
268 {
269 public Object doInHibernate(Session session) throws HibernateException
270 {
271 Query queryObject = session.getNamedQuery("atluser.group_getGroupsForUser");
272 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
273 queryObject.setLong(ENTITYID_FIELD, user.getId());
274 queryObject.setCacheable(true);
275 return queryObject.list();
276 }
277 });
278 }
279 catch (DataAccessException e)
280 {
281 throw new RepositoryException(e);
282 }
283 }
284 }