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 org.wamblee.security.AbstractPersistent;
19 import org.wamblee.security.encryption.MessageDigester;
21 import org.wamblee.usermgt.UserMgtException.Reason;
23 import java.io.Serializable;
26 import java.util.TreeSet;
28 import javax.persistence.CascadeType;
29 import javax.persistence.Entity;
30 import javax.persistence.FetchType;
31 import javax.persistence.GeneratedValue;
32 import javax.persistence.GenerationType;
33 import javax.persistence.Id;
34 import javax.persistence.ManyToMany;
35 import javax.persistence.NamedQueries;
36 import javax.persistence.NamedQuery;
37 import javax.persistence.Table;
38 import javax.persistence.Transient;
39 import javax.persistence.Version;
42 * Represents a user. The methods for managing the groups of the user have
43 * package scope. Managing the groups of the user should be done through the
44 * {@link org.wamblee.usermgt.UserAdministration} interface.
47 @Table(name = "SEC_USER")
49 @NamedQuery(name = User.QUERY_FIND_BY_NAME, query = "select u from User u where u.name = :" +
51 @NamedQuery(name = User.QUERY_FIND_BY_GROUP_NAME, query = "select user from User user join user.groups grp where grp.name = :name"),
52 @NamedQuery(name = User.QUERY_COUNT_USERS, query = "select count(u) from User u"),
53 @NamedQuery(name = User.QUERY_ALL_USERS, query = "select u from User u")})
54 public class User implements Serializable, Comparable {
56 public static final String QUERY_FIND_BY_NAME = "User.findByName";
57 public static final String QUERY_FIND_BY_GROUP_NAME = "User.findByGroupName";
58 public static final String QUERY_COUNT_USERS = "User.count";
59 public static final String QUERY_ALL_USERS = "User.all";
60 public static final String NAME_PARAM = "name";
63 @GeneratedValue(strategy = GenerationType.AUTO)
64 private Long primaryKey;
77 private String password;
80 * Groups the user belongs to.
82 @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
83 private Set<Group> groups;
89 private NameValidator passwordValidator;
95 private MessageDigester passwordEncoder;
98 * Constructs the user.
105 * Group the user belongs to.
107 User(String aName, String aPassword, Group aGroup,
108 NameValidator aPasswordValidator, MessageDigester aPasswordEncoder)
109 throws UserMgtException {
112 aPasswordValidator.validate(aPassword);
113 password = aPasswordEncoder.hash(aPassword);
114 groups = new TreeSet<Group>();
116 passwordValidator = aPasswordValidator;
117 passwordEncoder = aPasswordEncoder;
121 * Creates a new User object.
124 public User(User aUser) {
125 primaryKey = aUser.primaryKey;
126 version = aUser.version;
128 password = aUser.password;
129 groups = new TreeSet<Group>();
131 for (Group group : aUser.groups) {
132 groups.add(new Group(group));
135 passwordValidator = aUser.passwordValidator;
136 passwordEncoder = aUser.passwordEncoder;
140 * Creates a new User object.
147 passwordValidator = null;
148 passwordEncoder = null;
152 * Sets the password validator.
154 * @param aPasswordValidator
157 public void setPasswordValidator(NameValidator aPasswordValidator) {
158 passwordValidator = aPasswordValidator;
162 * Sets the password encoder.
164 * @param aPasswordEncoder
167 public void setPasswordEncoder(MessageDigester aPasswordEncoder) {
168 passwordEncoder = aPasswordEncoder;
173 * @return Returns the password.
175 String getPassword() {
180 * Checks the password.
185 * @throws UserMgtException
186 * In case the password is incorrect.
188 public void checkPassword(String aPassword) throws UserMgtException {
189 String encoded = passwordEncoder.hash(aPassword);
191 if (!password.equals(encoded)) {
192 throw new UserMgtException(Reason.INVALID_PASSWORD, this);
197 * Changes the password.
199 * @param aOldPassword
201 * @param aNewPassword
204 * @throws UserMgtException
205 * In case the old password is incorrect.
207 public void changePassword(String aOldPassword, String aNewPassword)
208 throws UserMgtException {
209 checkPassword(aOldPassword);
210 passwordValidator.validate(aNewPassword);
211 setPassword(aNewPassword);
217 * The password to set.
220 public void setPassword(String aPassword) throws UserMgtException {
221 passwordValidator.validate(aPassword);
222 password = passwordEncoder.hash(aPassword);
230 protected String getPasswordString() {
240 protected void setPasswordString(String aPassword) {
241 password = aPassword;
246 * @return Returns the _user.
248 public String getName() {
255 * The username to set.
257 void setName(String aName) {
262 * Gets the groups the user belongs to.
266 public Set<Group> getGroups() {
267 Set<Group> result = new TreeSet<Group>();
268 result.addAll(groups);
274 * Checks whether the user belongs to the given group.
279 * @return True if the user belongs to the group.
281 public boolean isInGroup(Group aGroup) {
282 return groups.contains(aGroup);
286 * Checks whether the user belongs to the given group.
291 * @return True if the user belongs to the group.
293 public boolean isInGroup(String aGroup) {
294 return groups.contains(new Group(aGroup));
298 * Gets the group set. For OR mapping.
300 * @return set of groups.
302 Set<Group> getGroupSet() {
307 * Sets the groups the user belongs to, for OR mapping.
312 void setGroupSet(Set<Group> aGroups) {
317 * Adds the user to a group.
320 * Group to add the user to.
322 * @throws UserMgtException
323 * In case the user already belongs to the group.
325 void addGroup(Group aGroup) throws UserMgtException {
326 if (groups.contains(aGroup)) {
327 throw new UserMgtException(Reason.USER_ALREADY_IN_GROUP, aGroup);
334 * Removes the user from a group.
339 * @throws UserMgtException
340 * In case the user does not belong to the group.
342 void removeGroup(Group aGroup) throws UserMgtException {
343 if (!groups.contains(aGroup)) {
344 throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup);
347 if (groups.size() == 1) {
348 throw new UserMgtException(Reason.USER_MUST_BE_IN_A_GROUP, this,
352 groups.remove(aGroup);
358 * @see java.lang.Object#equals(java.lang.Object)
361 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() {