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