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