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