]> WPIA git - gigi.git/blob - src/org/cacert/gigi/User.java
FIX: Cleanup fields
[gigi.git] / src / org / cacert / gigi / User.java
1 package org.cacert.gigi;
2
3 import java.sql.Date;
4 import java.sql.PreparedStatement;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.util.Calendar;
8
9 import org.cacert.gigi.database.DatabaseConnection;
10 import org.cacert.gigi.util.PasswordHash;
11 import org.cacert.gigi.util.PasswordStrengthChecker;
12
13 public class User {
14
15     private int id;
16
17     private Name name = new Name(null, null, null, null);
18
19     private Date dob;
20
21     private String email;
22
23     public User(int id) {
24         this.id = id;
25         try {
26             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT `fname`, `lname`,`mname`, `suffix`, `dob`, `email` FROM `users` WHERE id=?");
27             ps.setInt(1, id);
28             ResultSet rs = ps.executeQuery();
29             if (rs.next()) {
30                 name = new Name(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4));
31                 dob = rs.getDate(5);
32                 email = rs.getString(6);
33             }
34             rs.close();
35         } catch (SQLException e) {
36             e.printStackTrace();
37         }
38     }
39
40     public User() {}
41
42     public int getId() {
43         return id;
44     }
45
46     public String getFname() {
47         return name.fname;
48     }
49
50     public String getLname() {
51         return name.lname;
52     }
53
54     public String getMname() {
55         return name.mname;
56     }
57
58     public Name getName() {
59         return name;
60     }
61
62     public void setMname(String mname) {
63         this.name.mname = mname;
64     }
65
66     public String getSuffix() {
67         return name.suffix;
68     }
69
70     public void setSuffix(String suffix) {
71         this.name.suffix = suffix;
72     }
73
74     public Date getDob() {
75         return dob;
76     }
77
78     public void setDob(Date dob) {
79         this.dob = dob;
80     }
81
82     public String getEmail() {
83         return email;
84     }
85
86     public void setEmail(String email) {
87         this.email = email;
88     }
89
90     public void setId(int id) {
91         this.id = id;
92     }
93
94     public void setFname(String fname) {
95         this.name.fname = fname;
96     }
97
98     public void setLname(String lname) {
99         this.name.lname = lname;
100     }
101
102     public void insert(String password) throws SQLException {
103         if (id != 0) {
104             throw new Error("refusing to insert");
105         }
106         PreparedStatement query = DatabaseConnection.getInstance().prepare("insert into `users` set `email`=?, `password`=?, " + "`fname`=?, `mname`=?, `lname`=?, " + "`suffix`=?, `dob`=?, `created`=NOW(), locked=0");
107         query.setString(1, email);
108         query.setString(2, PasswordHash.hash(password));
109         query.setString(3, name.fname);
110         query.setString(4, name.mname);
111         query.setString(5, name.lname);
112         query.setString(6, name.suffix);
113         query.setDate(7, new java.sql.Date(dob.getTime()));
114         query.execute();
115         id = DatabaseConnection.lastInsertId(query);
116     }
117
118     public void changePassword(String oldPass, String newPass) throws GigiApiException {
119         try {
120             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT `password` FROM users WHERE id=?");
121             ps.setInt(1, id);
122             ResultSet rs = ps.executeQuery();
123             if ( !rs.next()) {
124                 throw new GigiApiException("User not found... very bad.");
125             }
126             if ( !PasswordHash.verifyHash(oldPass, rs.getString(1))) {
127                 throw new GigiApiException("Old password does not match.");
128             }
129             rs.close();
130             PasswordStrengthChecker.assertStrongPassword(newPass, this);
131             ps = DatabaseConnection.getInstance().prepare("UPDATE users SET `password`=? WHERE id=?");
132             ps.setString(1, PasswordHash.hash(newPass));
133             ps.setInt(2, id);
134             if (ps.executeUpdate() != 1) {
135                 throw new GigiApiException("Password update failed.");
136             }
137         } catch (SQLException e) {
138             throw new GigiApiException(e);
139         }
140     }
141
142     public boolean canAssure() throws SQLException {
143         if (getAssurancePoints() < 100) {
144             return false;
145         }
146
147         return hasPassedCATS();
148
149     }
150
151     public boolean hasPassedCATS() throws SQLException {
152         PreparedStatement query = DatabaseConnection.getInstance().prepare("SELECT 1 FROM `cats_passed` where `user_id`=?");
153         query.setInt(1, id);
154         ResultSet rs = query.executeQuery();
155         if (rs.next()) {
156             return true;
157         } else {
158             return false;
159         }
160     }
161
162     public int getAssurancePoints() throws SQLException {
163         PreparedStatement query = DatabaseConnection.getInstance().prepare("SELECT sum(points) FROM `notary` where `to`=? AND `deleted`=0");
164         query.setInt(1, id);
165         ResultSet rs = query.executeQuery();
166         int points = 0;
167         if (rs.next()) {
168             points = rs.getInt(1);
169         }
170         rs.close();
171         return points;
172     }
173
174     public int getExperiencePoints() throws SQLException {
175         PreparedStatement query = DatabaseConnection.getInstance().prepare("SELECT count(*) FROM `notary` where `from`=? AND `deleted`=0");
176         query.setInt(1, id);
177         ResultSet rs = query.executeQuery();
178         int points = 0;
179         if (rs.next()) {
180             points = rs.getInt(1) * 2;
181         }
182         rs.close();
183         return points;
184     }
185
186     @Override
187     public boolean equals(Object obj) {
188         if ( !(obj instanceof User)) {
189             return false;
190         }
191         User s = (User) obj;
192         return name.equals(s.name) && email.equals(s.email) && dob.toString().equals(s.dob.toString()); // This
193                                                                                                         // is
194                                                                                                         // due
195                                                                                                         // to
196                                                                                                         // day
197                                                                                                         // cutoff
198     }
199
200     /**
201      * Gets the maximum allowed points NOW. Note that an assurance needs to
202      * re-check PoJam as it has taken place in the past.
203      * 
204      * @return the maximal points
205      * @throws SQLException
206      */
207     public int getMaxAssurePoints() throws SQLException {
208         int exp = getExperiencePoints();
209         int points = 10;
210         Calendar c = Calendar.getInstance();
211         c.setTime(dob);
212         int year = c.get(Calendar.YEAR);
213         int month = c.get(Calendar.MONTH);
214         int day = c.get(Calendar.DAY_OF_MONTH);
215         c.set(year + 18, month, day);
216         if (System.currentTimeMillis() < c.getTime().getTime()) {
217             return points; // not 18 Years old.
218         }
219
220         if (exp >= 10) {
221             points += 5;
222         }
223         if (exp >= 20) {
224             points += 5;
225         }
226         if (exp >= 30) {
227             points += 5;
228         }
229         if (exp >= 40) {
230             points += 5;
231         }
232         if (exp >= 50) {
233             points += 5;
234         }
235         return points;
236     }
237
238     public static User getById(int id) {
239         return new User(id);
240     }
241
242     public EmailAddress[] getEmails() {
243         try {
244             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id FROM emails WHERE memid=? AND deleted=0");
245             ps.setInt(1, id);
246             ResultSet rs = ps.executeQuery();
247             rs.last();
248             int count = rs.getRow();
249             EmailAddress[] data = new EmailAddress[count];
250             rs.beforeFirst();
251             for (int i = 0; i < data.length; i++) {
252                 if ( !rs.next()) {
253                     throw new Error("Internal sql api violation.");
254                 }
255                 data[i] = EmailAddress.getById(rs.getInt(1));
256             }
257             rs.close();
258             return data;
259         } catch (SQLException e) {
260             e.printStackTrace();
261         }
262
263         return null;
264     }
265
266     public Domain[] getDomains() {
267         try {
268             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id FROM domains WHERE memid=? AND deleted IS NULL");
269             ps.setInt(1, id);
270             ResultSet rs = ps.executeQuery();
271             rs.last();
272             int count = rs.getRow();
273             Domain[] data = new Domain[count];
274             rs.beforeFirst();
275             for (int i = 0; i < data.length; i++) {
276                 if ( !rs.next()) {
277                     throw new Error("Internal sql api violation.");
278                 }
279                 data[i] = Domain.getById(rs.getInt(1));
280             }
281             rs.close();
282             return data;
283         } catch (SQLException e) {
284             e.printStackTrace();
285         }
286
287         return null;
288     }
289
290     public Certificate[] getCertificates() {
291         try {
292             PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT serial FROM certs WHERE memid=? AND revoked=0");
293             ps.setInt(1, id);
294             ResultSet rs = ps.executeQuery();
295             rs.last();
296             int count = rs.getRow();
297             Certificate[] data = new Certificate[count];
298             rs.beforeFirst();
299             for (int i = 0; i < data.length; i++) {
300                 if ( !rs.next()) {
301                     throw new Error("Internal sql api violation.");
302                 }
303                 data[i] = Certificate.getBySerial(rs.getString(1));
304             }
305             rs.close();
306             return data;
307         } catch (SQLException e) {
308             e.printStackTrace();
309         }
310
311         return null;
312     }
313
314     public boolean isValidDomain(String domainname) {
315         for (Domain d : getDomains()) {
316             String sfx = d.getSuffix();
317             if (domainname.equals(sfx) || domainname.endsWith("." + sfx)) {
318                 return true;
319             }
320         }
321         return false;
322     }
323
324     public boolean isValidEmail(String email) {
325         for (EmailAddress em : getEmails()) {
326             if (em.getAddress().equals(email)) {
327                 return true;
328             }
329         }
330         return false;
331     }
332
333     public boolean isValidName(String name) {
334         return getName().matches(name);
335     }
336
337     public void updateDefaultEmail(EmailAddress newMail) throws GigiApiException {
338         try {
339             EmailAddress[] adrs = getEmails();
340             for (int i = 0; i < adrs.length; i++) {
341                 if (adrs[i].getAddress().equals(newMail.getAddress())) {
342                     if ( !adrs[i].isVerified()) {
343                         throw new GigiApiException("Email not verified.");
344                     }
345                     PreparedStatement ps = DatabaseConnection.getInstance().prepare("UPDATE users SET email=? WHERE id=?");
346                     ps.setString(1, newMail.getAddress());
347                     ps.setInt(2, getId());
348                     ps.execute();
349                     email = newMail.getAddress();
350                     return;
351                 }
352             }
353             throw new GigiApiException("Given address not an address of the user.");
354         } catch (SQLException e) {
355             throw new GigiApiException(e);
356         }
357     }
358
359     public void deleteEmail(EmailAddress mail) throws GigiApiException {
360         if (getEmail().equals(mail.getAddress())) {
361             throw new GigiApiException("Can't delete user's default e-mail.");
362         }
363         EmailAddress[] emails = getEmails();
364         for (int i = 0; i < emails.length; i++) {
365             if (emails[i].getId() == mail.getId()) {
366                 try {
367                     PreparedStatement ps = DatabaseConnection.getInstance().prepare("UPDATE emails SET deleted=? WHERE id=?");
368                     ps.setDate(1, new Date(System.currentTimeMillis()));
369                     ps.setInt(2, mail.getId());
370                     ps.execute();
371                 } catch (SQLException e) {
372                     e.printStackTrace();
373                     throw new GigiApiException(e);
374                 }
375                 return;
376             }
377         }
378         throw new GigiApiException("Email not one of user's email addresses.");
379     }
380 }