428b068cc7aeeb5ba26ef3f6c25c88ecb42bd8e4
[gigi.git] / src / org / cacert / gigi / pages / main / Signup.java
1 package org.cacert.gigi.pages.main;
2
3 import java.io.IOException;
4 import java.io.InputStreamReader;
5 import java.io.PrintWriter;
6 import java.io.UnsupportedEncodingException;
7 import java.sql.PreparedStatement;
8 import java.sql.ResultSet;
9 import java.sql.SQLException;
10 import java.util.Date;
11 import java.util.HashMap;
12 import java.util.Map;
13
14 import javax.servlet.http.HttpServletRequest;
15
16 import org.cacert.gigi.Language;
17 import org.cacert.gigi.User;
18 import org.cacert.gigi.database.DatabaseConnection;
19 import org.cacert.gigi.email.EmailProvider;
20 import org.cacert.gigi.output.DateSelector;
21 import org.cacert.gigi.output.Form;
22 import org.cacert.gigi.output.Template;
23 import org.cacert.gigi.pages.Page;
24 import org.cacert.gigi.util.HTMLEncoder;
25 import org.cacert.gigi.util.Notary;
26 import org.cacert.gigi.util.PasswordStrengthChecker;
27 import org.cacert.gigi.util.RandomToken;
28 import org.cacert.gigi.util.ServerConstants;
29
30 public class Signup extends Form {
31         User buildup = new User();
32         Template t;
33         boolean general = true, country = true, regional = true, radius = true;
34         public Signup() {
35                 try {
36                         t = new Template(new InputStreamReader(
37                                         Signup.class.getResourceAsStream("Signup.templ"), "UTF-8"));
38                 } catch (UnsupportedEncodingException e) {
39                         e.printStackTrace();
40                 }
41                 buildup.setFname("");
42                 buildup.setMname("");
43                 buildup.setLname("");
44                 buildup.setSuffix("");
45                 buildup.setEmail("");
46                 buildup.setDob(new Date(0));
47         }
48         DateSelector myDoB = new DateSelector("day", "month", "year");
49
50         public void output(PrintWriter out, Language l,
51                         Map<String, Object> outerVars) {
52                 HashMap<String, Object> vars = new HashMap<String, Object>();
53                 vars.put("fname", HTMLEncoder.encodeHTML(buildup.getFname()));
54                 vars.put("mname", HTMLEncoder.encodeHTML(buildup.getMname()));
55                 vars.put("lname", HTMLEncoder.encodeHTML(buildup.getLname()));
56                 vars.put("suffix", HTMLEncoder.encodeHTML(buildup.getSuffix()));
57                 vars.put("dob", myDoB);
58                 vars.put("email", HTMLEncoder.encodeHTML(buildup.getEmail()));
59                 vars.put("general", general ? " checked=\"checked\"" : "");
60                 vars.put("country", country ? " checked=\"checked\"" : "");
61                 vars.put("regional", regional ? " checked=\"checked\"" : "");
62                 vars.put("radius", radius ? " checked=\"checked\"" : "");
63                 vars.put(
64                                 "helpOnNames",
65                                 String.format(
66                                                 l.getTranslation("Help on Names %sin the wiki%s"),
67                                                 "<a href=\"//wiki.cacert.org/FAQ/HowToEnterNamesInJoinForm\" target=\"_blank\">",
68                                                 "</a>"));
69                 t.output(out, l, vars);
70         }
71         private void update(HttpServletRequest r) {
72                 if (r.getParameter("fname") != null) {
73                         buildup.setFname(r.getParameter("fname"));
74                 }
75                 if (r.getParameter("lname") != null) {
76                         buildup.setLname(r.getParameter("lname"));
77                 }
78                 if (r.getParameter("mname") != null) {
79                         buildup.setMname(r.getParameter("mname"));
80                 }
81                 if (r.getParameter("suffix") != null) {
82                         buildup.setSuffix(r.getParameter("suffix"));
83                 }
84                 if (r.getParameter("email") != null) {
85                         buildup.setEmail(r.getParameter("email"));
86                 }
87                 general = "1".equals(r.getParameter("general"));
88                 country = "1".equals(r.getParameter("country"));
89                 regional = "1".equals(r.getParameter("regional"));
90                 radius = "1".equals(r.getParameter("radius"));
91                 myDoB.update(r);
92         }
93
94         @Override
95         public synchronized boolean submit(PrintWriter out, HttpServletRequest req) {
96                 update(req);
97                 boolean failed = false;
98                 out.println("<div class='formError'>");
99                 if (buildup.getFname().equals("") || buildup.getLname().equals("")) {
100                         outputError(out, req, "First and/or last names were blank.");
101                         failed = true;
102                 }
103                 if (!myDoB.isValid()) {
104                         outputError(out, req, "Invalid date of birth");
105                         failed = true;
106                 }
107                 if (!"1".equals(req.getParameter("cca_agree"))) {
108                         outputError(out, req,
109                                         "You have to agree to the CAcert Community agreement.");
110                         failed = true;
111                 }
112                 if (buildup.getEmail().equals("")) {
113                         outputError(out, req, "Email Address was blank");
114                         failed = true;
115                 }
116                 String pw1 = req.getParameter("pword1");
117                 String pw2 = req.getParameter("pword2");
118                 if (pw1 == null || pw1.equals("")) {
119                         outputError(out, req, "Pass Phrases were blank");
120                         failed = true;
121                 } else if (!pw1.equals(pw2)) {
122                         outputError(out, req, "Pass Phrases don't match");
123                         failed = true;
124                 }
125                 int pwpoints = PasswordStrengthChecker.checkpw(pw1, buildup);
126                 if (pwpoints < 3) {
127                         outputError(
128                                         out,
129                                         req,
130                                         "The Pass Phrase you submitted failed to contain enough"
131                                                         + " differing characters and/or contained words from"
132                                                         + " your name and/or email address.");
133                         failed = true;
134                 }
135                 if (failed) {
136                         out.println("</div>");
137                         return false;
138                 }
139                 try {
140                         PreparedStatement q1 = DatabaseConnection.getInstance().prepare(
141                                         "select * from `email` where `email`=? and `deleted`=0");
142                         PreparedStatement q2 = DatabaseConnection.getInstance().prepare(
143                                         "select * from `users` where `email`=? and `deleted`=0");
144                         q1.setString(1, buildup.getEmail());
145                         q2.setString(1, buildup.getEmail());
146                         ResultSet r1 = q1.executeQuery();
147                         ResultSet r2 = q2.executeQuery();
148                         if (r1.next() || r2.next()) {
149                                 outputError(out, req,
150                                                 "This email address is currently valid in the system.");
151                                 failed = true;
152                         }
153                         r1.close();
154                         r2.close();
155                         PreparedStatement q3 = DatabaseConnection
156                                         .getInstance()
157                                         .prepare(
158                                                         "select `domain` from `baddomains` where `domain`=RIGHT(?, LENGTH(`domain`))");
159                         q3.setString(1, buildup.getEmail());
160
161                         ResultSet r3 = q3.executeQuery();
162                         if (r3.next()) {
163                                 String domain = r3.getString(1);
164                                 out.print("<div>");
165                                 out.print(String.format(
166                                                 Page.translate(req,
167                                                                 "We don't allow signups from people using email addresses from %s"),
168                                                 domain));
169                                 out.println("</div>");
170                                 failed = true;
171                         }
172                         r3.close();
173                 } catch (SQLException e) {
174                         e.printStackTrace();
175                         failed = true;
176                 }
177                 String mailResult = EmailProvider.FAIL;
178                 try {
179                         mailResult = EmailProvider.getInstance().checkEmailServer(0,
180                                         buildup.getEmail());
181                 } catch (IOException e) {
182                 }
183                 if (!mailResult.equals(EmailProvider.OK)) {
184                         if (mailResult.startsWith("4")) {
185                                 outputError(
186                                                 out,
187                                                 req,
188                                                 "The mail server responsible for your domain indicated"
189                                                                 + " a temporary failure. This may be due to anti-SPAM measures, such"
190                                                                 + " as greylisting. Please try again in a few minutes.");
191                         } else {
192                                 outputError(
193                                                 out,
194                                                 req,
195                                                 "Email Address given was invalid, or a test connection"
196                                                                 + " couldn't be made to your server, or the server"
197                                                                 + " rejected the email address as invalid");
198                         }
199                         if (mailResult.equals(EmailProvider.FAIL)) {
200                                 outputError(out, req,
201                                                 "Failed to make a connection to the mail server");
202                         } else {
203                                 out.print("<div>");
204                                 out.print(mailResult);
205                                 out.println("</div>");
206                         }
207                         failed = true;
208                 }
209
210                 out.println("</div>");
211                 if (failed) {
212                         return false;
213                 }
214                 try {
215                         run(req, pw1);
216                 } catch (SQLException e) {
217                         e.printStackTrace();
218                 }
219                 return true;
220         }
221
222         private void run(HttpServletRequest req, String password)
223                         throws SQLException {
224                 try {
225                         DatabaseConnection.getInstance().beginTransaction();
226                         String hash = RandomToken.generateToken(16);
227
228                         buildup.setDob(myDoB.getDate());
229                         buildup.insert(password);
230                         int memid = buildup.getId();
231                         PreparedStatement ps = DatabaseConnection.getInstance().prepare(
232                                         "insert into `email` set `email`=?,"
233                                                         + " `hash`=?, `created`=NOW(),`memid`=?");
234                         ps.setString(1, buildup.getEmail());
235                         ps.setString(2, hash);
236                         ps.setInt(3, memid);
237                         ps.execute();
238                         int emailid = DatabaseConnection.lastInsertId(ps);
239                         ps = DatabaseConnection
240                                         .getInstance()
241                                         .prepare(
242                                                         "insert into `alerts` set `memid`=?,"
243                                                                         + " `general`=?, `country`=?, `regional`=?, `radius`=?");
244                         ps.setInt(1, memid);
245                         ps.setString(2, general ? "1" : "0");
246                         ps.setString(3, country ? "1" : "0");
247                         ps.setString(4, regional ? "1" : "0");
248                         ps.setString(5, radius ? "1" : "0");
249                         ps.execute();
250                         Notary.writeUserAgreement(memid, "CCA", "account creation", "",
251                                         true, 0);
252
253                         StringBuffer body = new StringBuffer();
254                         body.append(Page
255                                         .translate(
256                                                         req,
257                                                         "Thanks for signing up with CAcert.org, below is the link you need to open to verify your account. Once your account is verified you will be able to start issuing certificates till your hearts' content!"));
258                         body.append("\n\nhttps://");
259                         body.append(ServerConstants.getWwwHostNamePort());
260                         body.append("/verify?type=email&id=");
261                         body.append(emailid);
262                         body.append("&hash=");
263                         body.append(hash);
264                         body.append("\n\n");
265                         body.append(Page.translate(req, "Best regards"));
266                         body.append("\n");
267                         body.append(Page.translate(req, "CAcert.org Support!"));
268                         try {
269                                 EmailProvider.getInstance().sendmail(buildup.getEmail(),
270                                                 "[CAcert.org] " + Page.translate(req, "Mail Probe"),
271                                                 body.toString(), "support@cacert.org", null, null,
272                                                 null, null, false);
273                         } catch (IOException e) {
274                                 e.printStackTrace();
275                         }
276                         DatabaseConnection.getInstance().commitTransaction();
277                 } finally {
278                         DatabaseConnection.getInstance().quitTransaction();
279                 }
280
281         }
282 }