82a77303f6432b0dbedef95bfc6dbbd8fcfa0bc2
[utils] / security / impl / src / main / java / org / wamblee / security / authentication / User.java
1 /*
2  * Copyright 2005-2010 the original author or authors.
3  * 
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
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
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.
15  */
16 package org.wamblee.security.authentication;
17
18 import java.io.Serializable;
19 import java.util.Set;
20 import java.util.TreeSet;
21
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;
34
35 import org.wamblee.security.authentication.UserMgtException.Reason;
36 import org.wamblee.security.encryption.MessageDigester;
37
38 /**
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.security.authentication.UserAdministration} interface.
42  */
43 @Entity
44 @Table(name = "SEC_USER")
45 @NamedQueries( {
46     @NamedQuery(name = User.QUERY_FIND_BY_NAME, query = "select u from User u where u.name = :" +
47         User.NAME_PARAM),
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 {
52
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";
58
59     @Id
60     @GeneratedValue(strategy = GenerationType.AUTO)
61     private Long primaryKey;
62
63     @Version
64     private int version;
65
66     /**
67      * User name.
68      */
69     private String name;
70
71     /**
72      * Password.
73      */
74     private String password;
75
76     /**
77      * Groups the user belongs to.
78      */
79     @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
80     private Set<Group> groups;
81
82     /**
83      * Password validator.
84      */
85     @Transient
86     private NameValidator passwordValidator;
87
88     /**
89      * Password encoder.
90      */
91     @Transient
92     private MessageDigester passwordEncoder;
93
94     /**
95      * Constructs the user.
96      * 
97      * @param aName
98      *            User name.
99      * @param aPassword
100      *            Password.
101      */
102     User(String aName, String aPassword, NameValidator aPasswordValidator,
103         MessageDigester aPasswordEncoder) {
104         super();
105         name = aName;
106         aPasswordValidator.validate(aPassword);
107         password = aPasswordEncoder.hash(aPassword);
108         groups = new TreeSet<Group>();
109         passwordValidator = aPasswordValidator;
110         passwordEncoder = aPasswordEncoder;
111     }
112
113     /**
114      * Creates a new User object.
115      * 
116      */
117     public User(User aUser) {
118         primaryKey = aUser.primaryKey;
119         version = aUser.version;
120         name = aUser.name;
121         password = aUser.password;
122         groups = new TreeSet<Group>();
123
124         for (Group group : aUser.groups) {
125             groups.add(new Group(group));
126         }
127
128         passwordValidator = aUser.passwordValidator;
129         passwordEncoder = aUser.passwordEncoder;
130     }
131
132     /**
133      * Creates a new User object.
134      */
135     User() {
136         super();
137         name = null;
138         password = null;
139         groups = null;
140         passwordValidator = null;
141         passwordEncoder = null;
142     }
143
144     /**
145      * Sets the password validator.
146      * 
147      * @param aPasswordValidator
148      *            Validator.
149      */
150     public void setPasswordValidator(NameValidator aPasswordValidator) {
151         passwordValidator = aPasswordValidator;
152     }
153
154     /**
155      * Sets the password encoder.
156      * 
157      * @param aPasswordEncoder
158      *            Encoder.
159      */
160     public void setPasswordEncoder(MessageDigester aPasswordEncoder) {
161         passwordEncoder = aPasswordEncoder;
162     }
163
164     /**
165      * 
166      * @return Returns the password.
167      */
168     String getPassword() {
169         return password;
170     }
171
172     /**
173      * Checks the password.
174      * 
175      * @param aPassword
176      *            Password to check.
177      * 
178      * @return True iff the password is correct.
179      */
180     public boolean checkPassword(String aPassword) {
181         String encoded = passwordEncoder.hash(aPassword);
182
183         return password.equals(encoded);
184     }
185
186     /**
187      * Changes the password.
188      * 
189      * @param aOldPassword
190      *            Old password.
191      * @param aNewPassword
192      *            New password.
193      * 
194      * @return True iff the password was changed successfully.
195      */
196     public boolean changePassword(String aOldPassword, String aNewPassword) {
197         if (!checkPassword(aOldPassword)) {
198             return false;
199         }
200         passwordValidator.validate(aNewPassword);
201         setPassword(aNewPassword);
202         return true;
203     }
204
205     /**
206      * 
207      * @param aPassword
208      *            The password to set.
209      * 
210      */
211     public void setPassword(String aPassword) {
212         passwordValidator.validate(aPassword);
213         password = passwordEncoder.hash(aPassword);
214     }
215
216     /**
217      * For OR mapping.
218      * 
219      * @return Password.
220      */
221     protected String getPasswordString() {
222         return password;
223     }
224
225     /**
226      * For OR mapping.
227      * 
228      * @param aPassword
229      *            Password.
230      */
231     protected void setPasswordString(String aPassword) {
232         password = aPassword;
233     }
234
235     /**
236      * 
237      * @return Returns the _user.
238      */
239     public String getName() {
240         return name;
241     }
242
243     /**
244      * 
245      * @param aName
246      *            The username to set.
247      */
248     void setName(String aName) {
249         name = aName;
250     }
251
252     /**
253      * Gets the groups the user belongs to.
254      * 
255      * @return Groups.
256      */
257     public Set<Group> getGroups() {
258         Set<Group> result = new TreeSet<Group>();
259         result.addAll(groups);
260
261         return result;
262     }
263
264     /**
265      * Checks whether the user belongs to the given group.
266      * 
267      * @param aGroup
268      *            Group.
269      * 
270      * @return True if the user belongs to the group.
271      */
272     public boolean isInGroup(Group aGroup) {
273         return groups.contains(aGroup);
274     }
275
276     /**
277      * Checks whether the user belongs to the given group.
278      * 
279      * @param aGroup
280      *            Group.
281      * 
282      * @return True if the user belongs to the group.
283      */
284     public boolean isInGroup(String aGroup) {
285         return groups.contains(new Group(aGroup));
286     }
287
288     /**
289      * Gets the group set. For OR mapping.
290      * 
291      * @return set of groups.
292      */
293     Set<Group> getGroupSet() {
294         return groups;
295     }
296
297     /**
298      * Sets the groups the user belongs to, for OR mapping.
299      * 
300      * @param aGroups
301      *            Groups.
302      */
303     void setGroupSet(Set<Group> aGroups) {
304         groups = aGroups;
305     }
306
307     /**
308      * Adds the user to a group.
309      * 
310      * @param aGroup
311      *            Group to add the user to.
312      * 
313      * @throws UserMgtException
314      *             In case the user already belongs to the group.
315      */
316     void addGroup(Group aGroup) throws UserMgtException {
317         if (groups.contains(aGroup)) {
318             throw new UserMgtException(Reason.USER_ALREADY_IN_GROUP, aGroup);
319         }
320
321         groups.add(aGroup);
322     }
323
324     /**
325      * Removes the user from a group.
326      * 
327      * @param aGroup
328      *            Group.
329      * 
330      * @throws UserMgtException
331      *             In case the user does not belong to the group.
332      */
333     void removeGroup(Group aGroup) {
334         if (!groups.contains(aGroup)) {
335             throw new UserMgtException(Reason.USER_NOT_IN_GROUP, this, aGroup);
336         }
337
338         groups.remove(aGroup);
339     }
340
341     /*
342      * (non-Javadoc)
343      * 
344      * @see java.lang.Object#equals(java.lang.Object)
345      */
346     @Override
347     public boolean equals(Object aUser) {
348         if (aUser == null) {
349             return false;
350         }
351         if (!(aUser instanceof User)) {
352             return false;
353         }
354
355         User user = (User) aUser;
356
357         return name.equals(user.name);
358     }
359
360     /*
361      * (non-Javadoc)
362      * 
363      * @see java.lang.Object#hashCode()
364      */
365     @Override
366     public int hashCode() {
367         return name.hashCode();
368     }
369
370     /*
371      * (non-Javadoc)
372      * 
373      * @see java.lang.Object#toString()
374      */
375     @Override
376     public String toString() {
377         String result = "User(name=" + name + ", password=" + password;
378
379         for (Group group : groups) {
380             result += (", group=" + group);
381         }
382
383         return result + ")";
384     }
385
386     /*
387      * (non-Javadoc)
388      * 
389      * @see java.lang.Comparable#compareTo(T)
390      */
391     public int compareTo(Object aUser) {
392         return name.compareTo(((User) aUser).name);
393     }
394
395     public Long getPrimaryKey() {
396         return primaryKey;
397     }
398 }