Use exponential backoff when updating the password or last login time in WebDAV.
[pithos] / src / gr / ebs / gss / server / domain / Nonce.java
1 /*
2  * Copyright 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 java.io.UnsupportedEncodingException;
22 import java.net.URLEncoder;
23 import java.security.SecureRandom;
24 import java.util.Calendar;
25 import java.util.Date;
26
27 import javax.persistence.Entity;
28 import javax.persistence.GeneratedValue;
29 import javax.persistence.Id;
30 import javax.persistence.Temporal;
31 import javax.persistence.TemporalType;
32
33 import org.apache.commons.codec.binary.Base64;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.hibernate.annotations.Cache;
37 import org.hibernate.annotations.CacheConcurrencyStrategy;
38
39 /**
40  * The class that holds an issued nonce for a user.
41  *
42  * @author past
43  */
44 @Entity
45 @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
46 public class Nonce {
47
48         /**
49          * The logger.
50          */
51         private static Log logger = LogFactory.getLog(Nonce.class);
52
53         /**
54          * The nonce size in bytes.
55          */
56         private static final int NONCE_SIZE = 20;
57
58         /**
59          * The persistence ID of the object.
60          */
61         @Id
62         @GeneratedValue
63         private Long id;
64
65         /**
66          * The nonce issued for logging in this user.
67          */
68         private byte[] nonce;
69
70         /**
71          * The nonce encoded in Base64.
72          */
73         private String encodedNonce;
74
75         /**
76          * The time that the user's issued nonce
77          * will expire.
78          */
79         @Temporal(TemporalType.TIMESTAMP)
80         private Date nonceExpiryDate;
81
82
83         /**
84          * The ID of the user for whom this nonce was issued.
85          */
86         private Long userId;
87
88         /**
89          * Retrieve the id.
90          *
91          * @return the id
92          */
93         public Long getId() {
94                 return id;
95         }
96
97         /**
98          * Retrieve the nonce. If it is not valid or non-existent,
99          * this method returns null. Therefore, call sites must
100          * request a regeneration of the authentication token in
101          * both cases.
102          *
103          * @return the nonce
104          */
105         public byte[] getNonce() {
106                 if (isNonceValid())
107                         return nonce;
108                 return null;
109         }
110
111         /**
112          * Return true if the nonce is usable, or false
113          * if a new one must be regenerated.
114          *
115          * @return true if the nonce is valid
116          */
117         private boolean isNonceValid() {
118                 if (nonce == null)
119                         return false;
120                 if (nonceExpiryDate == null)
121                         return false;
122                 if (nonceExpiryDate.before(new Date()))
123                         return false;
124                 return true;
125         }
126
127         /**
128          * Creates a new nonce and resets its expiry date.
129          *
130          * @param userId the ID of the associated user
131          * @return a new nonce
132          */
133         public static Nonce createNonce(Long userId) {
134                 Nonce n = new Nonce();
135                 n.userId = userId;
136                 SecureRandom random = new SecureRandom();
137                 n.nonce = new byte[NONCE_SIZE];
138                 random.nextBytes(n.nonce);
139                 Calendar cal = Calendar.getInstance();
140                 // Set nonce time-to-live to 5 minutes.
141                 cal.add(Calendar.MINUTE, 5);
142                 n.nonceExpiryDate = cal.getTime();
143                 try {
144                         n.encodedNonce = URLEncoder.encode(new String(Base64.encodeBase64(n.nonce), "US-ASCII"), "US-ASCII");
145                 } catch (UnsupportedEncodingException e) {
146                         logger.error(e);
147                 }
148                 return n;
149         }
150
151         /**
152          * Retrieve the userId.
153          *
154          * @return the userId
155          */
156         public Long getUserId() {
157                 return userId;
158         }
159
160         /**
161          * Modify the nonce.
162          *
163          * @param aNonce the nonce to set
164          */
165         public void setNonce(byte[] aNonce) {
166                 nonce = aNonce;
167         }
168
169         /**
170          * Modify the nonceExpiryDate.
171          *
172          * @param aNonceExpiryDate the nonceExpiryDate to set
173          */
174         public void setNonceExpiryDate(Date aNonceExpiryDate) {
175                 nonceExpiryDate = aNonceExpiryDate;
176         }
177
178         /**
179          * Retrieve the encodedNonce.
180          *
181          * @return the encodedNonce
182          */
183         public String getEncodedNonce() {
184                 return encodedNonce;
185         }
186
187         /**
188          * Retrieve the nonceExpiryDate.
189          *
190          * @return the nonceExpiryDate
191          */
192         public Date getNonceExpiryDate() {
193                 return nonceExpiryDate;
194         }
195
196 }