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.security.authentication;
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.JoinColumn;
29 import javax.persistence.JoinTable;
30 import javax.persistence.ManyToMany;
31 import javax.persistence.NamedQueries;
32 import javax.persistence.NamedQuery;
33 import javax.persistence.Table;
34 import javax.persistence.Transient;
35 import javax.persistence.Version;
37 import org.wamblee.security.authentication.UserMgtException.Reason;
38 import org.wamblee.security.encryption.MessageDigester;
41 * Represents a user. The methods for managing the groups of the user have
42 * package scope. Managing the groups of the user should be done through the
43 * {@link org.wamblee.security.authentication.UserAdministration} interface.
46 @Table(name = "SEC_USER")
48 @NamedQuery(name = User.QUERY_FIND_BY_NAME, query = "select u from User u where u.name = :" +
50 @NamedQuery(name = User.QUERY_FIND_BY_GROUP_NAME, query = "select user from User user join user.groups grp where grp.name = :name"),
51 @NamedQuery(name = User.QUERY_COUNT_USERS, query = "select count(u) from User u"),
52 @NamedQuery(name = User.QUERY_ALL_USERS, query = "select u from User u") })
53 public class User implements Serializable, Comparable {
55 public static final String QUERY_FIND_BY_NAME = "User.findByName";
56 public static final String QUERY_FIND_BY_GROUP_NAME = "User.findByGroupName";
57 public static final String QUERY_COUNT_USERS = "User.count";
58 public static final String QUERY_ALL_USERS = "User.all";
59 public static final String NAME_PARAM = "name";
62 @GeneratedValue(strategy = GenerationType.AUTO)
76 private String password;
79 * Groups the user belongs to.
81 @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
82 @JoinTable(name = "SEC_USER_GROUP", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "GROUP_ID") })
83 private Set<Group> groups;
89 private NameValidator passwordValidator;
95 private MessageDigester passwordEncoder;
98 * Constructs the user.
105 User(String aName, String aPassword, NameValidator aPasswordValidator,
106 MessageDigester aPasswordEncoder) {
109 aPasswordValidator.validate(aPassword);
110 password = aPasswordEncoder.hash(aPassword);
111 groups = new TreeSet<Group>();
112 passwordValidator = aPasswordValidator;
113 passwordEncoder = aPasswordEncoder;
117 * Creates a new User object.
120 public User(User aUser) {
122 version = aUser.version;
124 password = aUser.password;
125 groups = new TreeSet<Group>();
127 for (Group group : aUser.groups) {
128 groups.add(new Group(group));
131 passwordValidator = aUser.passwordValidator;
132 passwordEncoder = aUser.passwordEncoder;
136 * Creates a new User object.
143 passwordValidator = null;
144 passwordEncoder = null;
148 * Sets the password validator.
150 * @param aPasswordValidator
153 public void setPasswordValidator(NameValidator aPasswordValidator) {
154 passwordValidator = aPasswordValidator;
158 * Sets the password encoder.
160 * @param aPasswordEncoder
163 public void setPasswordEncoder(MessageDigester aPasswordEncoder) {
164 passwordEncoder = aPasswordEncoder;
169 * @return Returns the password.
171 String getPassword() {
176 * Checks the password.
181 * @return True iff the password is correct.
183 public boolean checkPassword(String aPassword) {
184 String encoded = passwordEncoder.hash(aPassword);
186 return password.equals(encoded);
190 * Changes the password.
192 * @param aOldPassword
194 * @param aNewPassword
197 * @return True iff the password was changed successfully.
199 public boolean changePassword(String aOldPassword, String aNewPassword) {
200 if (!checkPassword(aOldPassword)) {
203 passwordValidator.validate(aNewPassword);
204 setPassword(aNewPassword);
211 * The password to set.
214 public void setPassword(String aPassword) {
215 passwordValidator.validate(aPassword);
216 password = passwordEncoder.hash(aPassword);
224 protected String getPasswordString() {
234 protected void setPasswordString(String aPassword) {
235 password = aPassword;
240 * @return Returns the _user.
242 public String getName() {
249 * The username to set.
251 void setName(String aName) {
256 * Gets the groups the user belongs to.
260 public Set<Group> getGroups() {
261 Set<Group> result = new TreeSet<Group>();
262 result.addAll(groups);
268 * Checks whether the user belongs to the given group.
273 * @return True if the user belongs to the group.
275 public boolean isInGroup(Group aGroup) {
276 return groups.contains(aGroup);
280 * Checks whether the user belongs to the given group.
285 * @return True if the user belongs to the group.
287 public boolean isInGroup(String aGroup) {
288 return groups.contains(new Group(aGroup));
292 * Gets the group set. For OR mapping.
294 * @return set of groups.
296 Set<Group> getGroupSet() {
301 * Sets the groups the user belongs to, for OR mapping.
306 void setGroupSet(Set<Group> aGroups) {
311 * Adds the user to a group.
314 * Group to add the user to.
316 * @throws UserMgtException
317 * In case the user already belongs to the group.
319 void addGroup(Group aGroup) throws UserMgtException {
320 if (groups.contains(aGroup)) {
321 throw new UserMgtException(Reason.USER_ALREADY_IN_GROUP, aGroup);
328 * Removes the user from a group.
333 * @throws UserMgtException
334 * In case the user does not belong to the group.
336 void removeGroup(Group aGroup) {
337 if (!groups.contains(aGroup)) {
338 throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup);
341 groups.remove(aGroup);
347 * @see java.lang.Object#equals(java.lang.Object)
350 public boolean equals(Object aUser) {
354 if (!(aUser instanceof User)) {
358 User user = (User) aUser;
360 return name.equals(user.name);
366 * @see java.lang.Object#hashCode()
369 public int hashCode() {
370 return name.hashCode();
376 * @see java.lang.Object#toString()
379 public String toString() {
380 String result = "User(name=" + name + ", password=" + password;
382 for (Group group : groups) {
383 result += (", group=" + group);
392 * @see java.lang.Comparable#compareTo(T)
394 public int compareTo(Object aUser) {
395 return name.compareTo(((User) aUser).name);
398 public Long getPrimaryKey() {