Fixed bug: Uploading a new version of a versioned file with no quota left would leave...
[pithos] / src / gr / ebs / gss / server / domain / User.java
1 /*
2  * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
3  *
4  * This file is part of GSS.
5  *
6  * GSS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 package gr.ebs.gss.server.domain;
20
21 import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
22 import gr.ebs.gss.server.domain.dto.UserDTO;
23
24 import java.io.Serializable;
25 import java.security.SecureRandom;
26 import java.util.Calendar;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.Set;
30
31 import javax.persistence.CascadeType;
32 import javax.persistence.Column;
33 import javax.persistence.Embedded;
34 import javax.persistence.Entity;
35 import javax.persistence.FetchType;
36 import javax.persistence.GeneratedValue;
37 import javax.persistence.Id;
38 import javax.persistence.ManyToMany;
39 import javax.persistence.ManyToOne;
40 import javax.persistence.OneToMany;
41 import javax.persistence.OrderBy;
42 import javax.persistence.Table;
43 import javax.persistence.Temporal;
44 import javax.persistence.TemporalType;
45 import javax.persistence.Version;
46
47 /**
48  * The class that holds information about a particular user of the system.
49  *
50  * @author past
51  */
52 @Entity
53 @Table(name = "GSS_User")
54 public class User implements Serializable {
55
56         /**
57          * The authentication token size in bytes.
58          */
59         private static final int TOKEN_SIZE = 40;
60
61         /**
62          * The persistence ID of the object.
63          */
64         @Id
65         @GeneratedValue
66         private Long id;
67
68         /**
69          * Version field for optimistic locking.
70          */
71         @SuppressWarnings("unused")
72         @Version
73         private int version;
74
75         /**
76          * The audit information.
77          */
78         @Embedded
79         private AuditInfo auditInfo;
80
81         /**
82          * The first name of the user.
83          */
84         private String firstname;
85
86         /**
87          * The last name of the user.
88          */
89         private String lastname;
90
91         /**
92          * The full name of the user.
93          */
94         private String name;
95
96         /**
97          * The username of the user.
98          */
99         @Column(unique = true)
100         private String username;
101
102         /**
103          * The e-mail address of the user.
104          */
105         private String email;
106
107         /**
108          * The list of groups that have been specified by this user.
109          */
110         @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
111         @OrderBy("name")
112         private List<Group> groupsSpecified;
113
114         /**
115          * The set of groups of which this user is member.
116          */
117         @ManyToMany(fetch = FetchType.LAZY, mappedBy = "members")
118         private Set<Group> groupsMember;
119
120         /**
121          * The list of all tags this user has specified on all files.
122          */
123         @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
124         @OrderBy("tag")
125         private List<FileTag> fileTags;
126
127         /**
128          * The user class to which this user belongs.
129          */
130         @ManyToOne
131         private UserClass userClass;
132
133         /**
134          * The authentication token issued for this user.
135          */
136         private byte[] authToken;
137
138         /**
139          * The time that the user's issued authentication token
140          * will expire.
141          */
142         @Temporal(TemporalType.TIMESTAMP)
143         private Date authTokenExpiryDate;
144
145         /**
146          * The active nonce issued for logging in this user, in
147          * Base64 encoding.
148          */
149         private String nonce;
150
151         /**
152          * The active nonce expiry date.
153          */
154         private Date nonceExpiryDate;
155
156         /**
157          * Flag that denotes whether the user has accepted the
158          * terms and conditions of the service.
159          * XXX: the columnDefinition is postgres specific, if deployment database is changed this shall be changed too
160          */
161         @Column(columnDefinition=" boolean DEFAULT false")
162         private boolean acceptedPolicy;
163
164         /**
165          * Retrieve the firstname.
166          *
167          * @return the firstname
168          */
169         public String getFirstname() {
170                 return firstname;
171         }
172
173         /**
174          * Modify the firstname.
175          *
176          * @param newFirstname the firstname to set
177          */
178         public void setFirstname(final String newFirstname) {
179                 firstname = newFirstname;
180         }
181
182         /**
183          * Retrieve the lastname.
184          *
185          * @return the lastname
186          */
187         public String getLastname() {
188                 return lastname;
189         }
190
191         /**
192          * Modify the lastname.
193          *
194          * @param newLastname the lastname to set
195          */
196         public void setLastname(final String newLastname) {
197                 lastname = newLastname;
198         }
199
200         /**
201          * Retrieve the name.
202          *
203          * @return the name
204          */
205         public String getName() {
206                 return name;
207         }
208
209         /**
210          * Modify the name.
211          *
212          * @param newName the name to set
213          */
214         public void setName(final String newName) {
215                 name = newName;
216         }
217
218         /**
219          * Retrieve the email.
220          *
221          * @return the email
222          */
223         public String getEmail() {
224                 return email;
225         }
226
227         /**
228          * Modify the email.
229          *
230          * @param newEmail the email to set
231          */
232         public void setEmail(final String newEmail) {
233                 email = newEmail;
234         }
235
236         /**
237          * Retrieve the id.
238          *
239          * @return the id
240          */
241         public Long getId() {
242                 return id;
243         }
244
245         /**
246          * Retrieve the groups specified by this user.
247          *
248          * @return the groups
249          */
250         public List<Group> getGroupsSpecified() {
251                 return groupsSpecified;
252         }
253
254         /**
255          * Modify the groups specified by this user.
256          *
257          * @param newGroupsSpecified the groups to set
258          */
259         public void setGroupsSpecified(final List<Group> newGroupsSpecified) {
260                 groupsSpecified = newGroupsSpecified;
261         }
262
263         /**
264          * Retrieve the groups of which this user is member.
265          *
266          * @return the groups
267          */
268         public Set<Group> getGroupsMember() {
269                 return groupsMember;
270         }
271
272         /**
273          * Modify the groups of which this user is member.
274          *
275          * @param newGroupsMember the groups to set
276          */
277         public void setGroupsMember(final Set<Group> newGroupsMember) {
278                 groupsMember = newGroupsMember;
279         }
280
281         /**
282          * Retrieve the audit info.
283          *
284          * @return the audit info
285          */
286         public AuditInfo getAuditInfo() {
287                 return auditInfo;
288         }
289
290         /**
291          * Modify the audit info.
292          *
293          * @param newAuditInfo the new audit info
294          */
295         public void setAuditInfo(final AuditInfo newAuditInfo) {
296                 auditInfo = newAuditInfo;
297         }
298
299         /**
300          * Retrieve the file tags.
301          *
302          * @return a list of file tags
303          */
304         public List<FileTag> getFileTags() {
305                 return fileTags;
306         }
307
308         /**
309          * Replace the list of file tags.
310          *
311          * @param newFileTags the new file tags
312          */
313         public void setFileTags(final List<FileTag> newFileTags) {
314                 fileTags = newFileTags;
315         }
316
317         /**
318          * Retrieve the user class.
319          *
320          * @return the user class
321          */
322         public UserClass getUserClass() {
323                 return userClass;
324         }
325
326         /**
327          * Modify the user class.
328          *
329          * @param newUserClass the new user class
330          */
331         public void setUserClass(final UserClass newUserClass) {
332                 userClass = newUserClass;
333         }
334
335         // ********************** Business Methods ********************** //
336
337
338
339         /**
340          * Retrieve the username.
341          *
342          * @return the username
343          */
344         public String getUsername() {
345                 return username;
346         }
347
348
349         /**
350          * Modify the username.
351          *
352          * @param aUsername the username to set
353          */
354         public void setUsername(String aUsername) {
355                 username = aUsername;
356         }
357
358         /**
359          * Retrieve the authentication token. If it is not valid
360          * or non-existent, this method returns null. Therefore, call
361          * sites must request a regeneration of the authentication
362          * token in both cases.
363          *
364          * @return the authToken
365          */
366         public byte[] getAuthToken() {
367                 if (isAuthTokenValid())
368                         return authToken;
369                 return null;
370         }
371
372         /**
373          * Add a tag from this user to specified file.
374          *
375          * @param file the file
376          * @param tag the tag string
377          */
378         public void addTag(final FileHeader file, final String tag) {
379                 @SuppressWarnings("unused")
380                 final FileTag fileTag = new FileTag(this, file, tag);
381                 // Cascade should take care of saving here.
382         }
383
384         /**
385          * Return a Data Transfer Object for this User object.
386          *
387          * @return a user DTO
388          */
389         public UserDTO getDTO() {
390                 final UserDTO u = new UserDTO();
391                 u.setId(id);
392                 u.setName(name);
393                 u.setLastname(lastname);
394                 u.setFirstname(firstname);
395                 u.setEmail(email);
396                 u.setUsername(username);
397                 return u;
398         }
399
400         /**
401          * Removes a group from this user's specified groups list.
402          *
403          * @param group the group to remove
404          * @throws IllegalArgumentException if group is null
405          */
406         public void removeSpecifiedGroup(final Group group) {
407                 if (group == null)
408                         throw new IllegalArgumentException("Can't remove a null group.");
409                 getGroupsSpecified().remove(group);
410                 group.setOwner(null);
411         }
412
413         /**
414          * @param name2
415          */
416         public void createGroup(final String name2) {
417                 final Group group = new Group(name2);
418                 group.setOwner(this);
419                 final Date now = new Date();
420                 final AuditInfo ai = new AuditInfo();
421                 ai.setCreatedBy(this);
422                 ai.setCreationDate(now);
423                 ai.setModifiedBy(this);
424                 ai.setModificationDate(now);
425                 group.setAuditInfo(ai);
426                 groupsSpecified.add(group);
427         }
428
429         /**
430          * Removes the specified tag from this user
431          *
432          * @param tag
433          */
434         public void removeTag(FileTag tag) {
435                 fileTags.remove(tag);
436                 tag.setUser(null);
437         }
438
439         /**
440          * Creates a new authentication token and resets
441          * its expiry date.
442          */
443         public void generateAuthToken() {
444                 SecureRandom random = new SecureRandom();
445                 authToken = new byte[TOKEN_SIZE];
446                 random.nextBytes(authToken);
447                 Calendar cal = Calendar.getInstance();
448                 // Set token time-to-live to the number of days specified in
449                 // gss.properties.
450                 cal.add(Calendar.DAY_OF_MONTH, getConfiguration().getInt("tokenTTL", 1));
451                 authTokenExpiryDate = cal.getTime();
452         }
453
454         /**
455          * Return true if the authentication token is usable, or false
456          * if a new one must be regenerated.
457          *
458          * @return true if the authentication token is valid
459          */
460         private boolean isAuthTokenValid() {
461                 if (authToken == null)
462                         return false;
463                 if (authTokenExpiryDate == null)
464                         return false;
465                 if (authTokenExpiryDate.before(new Date()))
466                         return false;
467                 return true;
468         }
469
470         /**
471          * Request the invalidation of the authentication token.
472          * After this method is called, a new token must be generated.
473          */
474         public void invalidateAuthToken() {
475                 authToken = null;
476                 authTokenExpiryDate = null;
477         }
478
479         /**
480          * Retrieve the nonce. If it is not valid or non-existent,
481          * this method returns null.
482          *
483          * @return the nonce
484          */
485         public String getNonce() {
486                 if (isNonceValid())
487                         return nonce;
488                 return null;
489         }
490
491         /**
492          * Return true if the nonce is usable, or false
493          * if not.
494          *
495          * @return true if the nonce is valid
496          */
497         private boolean isNonceValid() {
498                 if (nonce == null)
499                         return false;
500                 if (nonceExpiryDate == null)
501                         return false;
502                 if (nonceExpiryDate.before(new Date()))
503                         return false;
504                 return true;
505         }
506
507         /**
508          * Modify the nonce.
509          *
510          * @param aNonce the nonce to set
511          */
512         public void setNonce(String aNonce) {
513                 nonce = aNonce;
514         }
515
516         /**
517          * Modify the nonce expiry date.
518          *
519          * @param aNonceExpiryDate the nonce expiry date to set
520          */
521         public void setNonceExpiryDate(Date aNonceExpiryDate) {
522                 nonceExpiryDate = aNonceExpiryDate;
523         }
524
525         @Override
526         public boolean equals(Object o) {
527                 if (this == o) return true;
528                 if (!(o instanceof User)) return false;
529                 User user = (User) o;
530                 return user.getUsername().equals(username) && user.getName().equals(name);
531         }
532
533         @Override
534         public int hashCode() {
535                 return 37 * username.hashCode() + name.hashCode();
536         }
537
538         /**
539          * Retrieve the acceptedPolicy flag.
540          *
541          * @return the acceptedPolicy
542          */
543         public boolean hasAcceptedPolicy() {
544                 return acceptedPolicy;
545         }
546
547         /**
548          * Modify the acceptedPolicy flag.
549          *
550          * @param newAcceptedPolicy the acceptedPolicy to set
551          */
552         public void setAcceptedPolicy(boolean newAcceptedPolicy) {
553                 acceptedPolicy = newAcceptedPolicy;
554         }
555 }