2 * Copyright 2005-2010 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.usermgt;
18 import java.io.Serializable;
20 import java.util.TreeSet;
22 import javax.persistence.CascadeType;
23 import javax.persistence.Entity;
24 import javax.persistence.FetchType;
25 import javax.persistence.GeneratedValue;
26 import javax.persistence.GenerationType;
27 import javax.persistence.Id;
28 import javax.persistence.ManyToMany;
29 import javax.persistence.NamedQueries;
30 import javax.persistence.NamedQuery;
31 import javax.persistence.Table;
32 import javax.persistence.Transient;
33 import javax.persistence.Version;
35 import org.wamblee.security.encryption.MessageDigester;
36 import org.wamblee.usermgt.UserMgtException.Reason;
39 * Represents a user. The methods for managing the groups of the user have
40 * package scope. Managing the groups of the user should be done through the
41 * {@link org.wamblee.usermgt.UserAdministration} interface.
44 @Table(name = "SEC_USER")
46 @NamedQuery(name = User.QUERY_FIND_BY_NAME, query = "select u from User u where u.name = :" +
48 @NamedQuery(name = User.QUERY_FIND_BY_GROUP_NAME, query = "select user from User user join user.groups grp where grp.name = :name"),
49 @NamedQuery(name = User.QUERY_COUNT_USERS, query = "select count(u) from User u"),
50 @NamedQuery(name = User.QUERY_ALL_USERS, query = "select u from User u") })
51 public class User implements Serializable, Comparable {
53 public static final String QUERY_FIND_BY_NAME = "User.findByName";
54 public static final String QUERY_FIND_BY_GROUP_NAME = "User.findByGroupName";
55 public static final String QUERY_COUNT_USERS = "User.count";
56 public static final String QUERY_ALL_USERS = "User.all";
57 public static final String NAME_PARAM = "name";
60 @GeneratedValue(strategy = GenerationType.AUTO)
61 private Long primaryKey;
74 private String password;
77 * Groups the user belongs to.
79 @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
80 private Set<Group> groups;
86 private NameValidator passwordValidator;
92 private MessageDigester passwordEncoder;
95 * Constructs the user.
102 * Group the user belongs to.
104 User(String aName, String aPassword, Group aGroup,
105 NameValidator aPasswordValidator, MessageDigester aPasswordEncoder)
106 throws UserMgtException {
109 aPasswordValidator.validate(aPassword);
110 password = aPasswordEncoder.hash(aPassword);
111 groups = new TreeSet<Group>();
113 passwordValidator = aPasswordValidator;
114 passwordEncoder = aPasswordEncoder;
118 * Creates a new User object.
121 public User(User aUser) {
122 primaryKey = aUser.primaryKey;
123 version = aUser.version;
125 password = aUser.password;
126 groups = new TreeSet<Group>();
128 for (Group group : aUser.groups) {
129 groups.add(new Group(group));
132 passwordValidator = aUser.passwordValidator;
133 passwordEncoder = aUser.passwordEncoder;
137 * Creates a new User object.
144 passwordValidator = null;
145 passwordEncoder = null;
149 * Sets the password validator.
151 * @param aPasswordValidator
154 public void setPasswordValidator(NameValidator aPasswordValidator) {
155 passwordValidator = aPasswordValidator;
159 * Sets the password encoder.
161 * @param aPasswordEncoder
164 public void setPasswordEncoder(MessageDigester aPasswordEncoder) {
165 passwordEncoder = aPasswordEncoder;
170 * @return Returns the password.
172 String getPassword() {
177 * Checks the password.
182 * @throws UserMgtException
183 * In case the password is incorrect.
185 public void checkPassword(String aPassword) throws UserMgtException {
186 String encoded = passwordEncoder.hash(aPassword);
188 if (!password.equals(encoded)) {
189 throw new UserMgtException(Reason.INVALID_PASSWORD, this);
194 * Changes the password.
196 * @param aOldPassword
198 * @param aNewPassword
201 * @throws UserMgtException
202 * In case the old password is incorrect.
204 public void changePassword(String aOldPassword, String aNewPassword)
205 throws UserMgtException {
206 checkPassword(aOldPassword);
207 passwordValidator.validate(aNewPassword);
208 setPassword(aNewPassword);
214 * The password to set.
217 public void setPassword(String aPassword) throws UserMgtException {
218 passwordValidator.validate(aPassword);
219 password = passwordEncoder.hash(aPassword);
227 protected String getPasswordString() {
237 protected void setPasswordString(String aPassword) {
238 password = aPassword;
243 * @return Returns the _user.
245 public String getName() {
252 * The username to set.
254 void setName(String aName) {
259 * Gets the groups the user belongs to.
263 public Set<Group> getGroups() {
264 Set<Group> result = new TreeSet<Group>();
265 result.addAll(groups);
271 * Checks whether the user belongs to the given group.
276 * @return True if the user belongs to the group.
278 public boolean isInGroup(Group aGroup) {
279 return groups.contains(aGroup);
283 * Checks whether the user belongs to the given group.
288 * @return True if the user belongs to the group.
290 public boolean isInGroup(String aGroup) {
291 return groups.contains(new Group(aGroup));
295 * Gets the group set. For OR mapping.
297 * @return set of groups.
299 Set<Group> getGroupSet() {
304 * Sets the groups the user belongs to, for OR mapping.
309 void setGroupSet(Set<Group> aGroups) {
314 * Adds the user to a group.
317 * Group to add the user to.
319 * @throws UserMgtException
320 * In case the user already belongs to the group.
322 void addGroup(Group aGroup) throws UserMgtException {
323 if (groups.contains(aGroup)) {
324 throw new UserMgtException(Reason.USER_ALREADY_IN_GROUP, aGroup);
331 * Removes the user from a group.
336 * @throws UserMgtException
337 * In case the user does not belong to the group.
339 void removeGroup(Group aGroup) throws UserMgtException {
340 if (!groups.contains(aGroup)) {
341 throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup);
344 if (groups.size() == 1) {
345 throw new UserMgtException(Reason.USER_MUST_BE_IN_A_GROUP, this,
349 groups.remove(aGroup);
355 * @see java.lang.Object#equals(java.lang.Object)
358 public boolean equals(Object aUser) {
362 if (!(aUser instanceof User)) {
366 User user = (User) aUser;
368 return name.equals(user.name);
374 * @see java.lang.Object#hashCode()
377 public int hashCode() {
378 return name.hashCode();
384 * @see java.lang.Object#toString()
387 public String toString() {
388 String result = "User(name=" + name + ", password=" + password;
390 for (Group group : groups) {
391 result += (", group=" + group);
400 * @see java.lang.Comparable#compareTo(T)
402 public int compareTo(Object aUser) {
403 return name.compareTo(((User) aUser).name);
406 public Long getPrimaryKey() {