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