]> WPIA git - gigi.git/blob - src/org/cacert/gigi/pages/main/Signup.java
Correct csrf-token impl.
[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.sql.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
35         public Signup(HttpServletRequest hsr) {
36                 super(hsr);
37                 try {
38                         t = new Template(new InputStreamReader(Signup.class.getResourceAsStream("Signup.templ"), "UTF-8"));
39                 } catch (UnsupportedEncodingException e) {
40                         e.printStackTrace();
41                 }
42                 buildup.setFname("");
43                 buildup.setMname("");
44                 buildup.setLname("");
45                 buildup.setSuffix("");
46                 buildup.setEmail("");
47                 buildup.setDob(new Date(0));
48         }
49
50         DateSelector myDoB = new DateSelector("day", "month", "year");
51
52         @Override
53         public void outputContent(PrintWriter out, Language l, Map<String, Object> outerVars) {
54                 HashMap<String, Object> vars = new HashMap<String, Object>();
55                 vars.put("fname", HTMLEncoder.encodeHTML(buildup.getFname()));
56                 vars.put("mname", HTMLEncoder.encodeHTML(buildup.getMname()));
57                 vars.put("lname", HTMLEncoder.encodeHTML(buildup.getLname()));
58                 vars.put("suffix", HTMLEncoder.encodeHTML(buildup.getSuffix()));
59                 vars.put("dob", myDoB);
60                 vars.put("email", HTMLEncoder.encodeHTML(buildup.getEmail()));
61                 vars.put("general", general ? " checked=\"checked\"" : "");
62                 vars.put("country", country ? " checked=\"checked\"" : "");
63                 vars.put("regional", regional ? " checked=\"checked\"" : "");
64                 vars.put("radius", radius ? " checked=\"checked\"" : "");
65                 vars.put("helpOnNames", String.format(l.getTranslation("Help on Names %sin the wiki%s"),
66                         "<a href=\"//wiki.cacert.org/FAQ/HowToEnterNamesInJoinForm\" target=\"_blank\">", "</a>"));
67                 vars.put("csrf", getCSRFToken());
68                 t.output(out, l, vars);
69         }
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, "You have to agree to the CAcert Community agreement.");
109                         failed = true;
110                 }
111                 if (buildup.getEmail().equals("")) {
112                         outputError(out, req, "Email Address was blank");
113                         failed = true;
114                 }
115                 String pw1 = req.getParameter("pword1");
116                 String pw2 = req.getParameter("pword2");
117                 if (pw1 == null || pw1.equals("")) {
118                         outputError(out, req, "Pass Phrases were blank");
119                         failed = true;
120                 } else if (!pw1.equals(pw2)) {
121                         outputError(out, req, "Pass Phrases don't match");
122                         failed = true;
123                 }
124                 int pwpoints = PasswordStrengthChecker.checkpw(pw1, buildup);
125                 if (pwpoints < 3) {
126                         outputError(out, req, "The Pass Phrase you submitted failed to contain enough"
127                                 + " differing characters and/or contained words from" + " your name and/or email address.");
128                         failed = true;
129                 }
130                 if (failed) {
131                         out.println("</div>");
132                         return false;
133                 }
134                 try {
135                         PreparedStatement q1 = DatabaseConnection.getInstance().prepare(
136                                 "select * from `email` where `email`=? and `deleted`=0");
137                         PreparedStatement q2 = DatabaseConnection.getInstance().prepare(
138                                 "select * from `users` where `email`=? and `deleted`=0");
139                         q1.setString(1, buildup.getEmail());
140                         q2.setString(1, buildup.getEmail());
141                         ResultSet r1 = q1.executeQuery();
142                         ResultSet r2 = q2.executeQuery();
143                         if (r1.next() || r2.next()) {
144                                 outputError(out, req, "This email address is currently valid in the system.");
145                                 failed = true;
146                         }
147                         r1.close();
148                         r2.close();
149                         PreparedStatement q3 = DatabaseConnection.getInstance().prepare(
150                                 "select `domain` from `baddomains` where `domain`=RIGHT(?, LENGTH(`domain`))");
151                         q3.setString(1, buildup.getEmail());
152
153                         ResultSet r3 = q3.executeQuery();
154                         if (r3.next()) {
155                                 String domain = r3.getString(1);
156                                 out.print("<div>");
157                                 out.print(String.format(
158                                         Page.translate(req, "We don't allow signups from people using email addresses from %s"), domain));
159                                 out.println("</div>");
160                                 failed = true;
161                         }
162                         r3.close();
163                 } catch (SQLException e) {
164                         e.printStackTrace();
165                         failed = true;
166                 }
167                 String mailResult = EmailProvider.FAIL;
168                 try {
169                         mailResult = EmailProvider.getInstance().checkEmailServer(0, buildup.getEmail());
170                 } catch (IOException e) {
171                 }
172                 if (!mailResult.equals(EmailProvider.OK)) {
173                         if (mailResult.startsWith("4")) {
174                                 outputError(out, req, "The mail server responsible for your domain indicated"
175                                         + " a temporary failure. This may be due to anti-SPAM measures, such"
176                                         + " as greylisting. Please try again in a few minutes.");
177                         } else {
178                                 outputError(out, req, "Email Address given was invalid, or a test connection"
179                                         + " couldn't be made to your server, or the server" + " rejected the email address as invalid");
180                         }
181                         if (mailResult.equals(EmailProvider.FAIL)) {
182                                 outputError(out, req, "Failed to make a connection to the mail server");
183                         } else {
184                                 out.print("<div>");
185                                 out.print(mailResult);
186                                 out.println("</div>");
187                         }
188                         failed = true;
189                 }
190
191                 out.println("</div>");
192                 if (failed) {
193                         return false;
194                 }
195                 try {
196                         run(req, pw1);
197                 } catch (SQLException e) {
198                         e.printStackTrace();
199                 }
200                 return true;
201         }
202
203         private void run(HttpServletRequest req, String password) throws SQLException {
204                 try {
205                         DatabaseConnection.getInstance().beginTransaction();
206                         String hash = RandomToken.generateToken(16);
207
208                         buildup.setDob(myDoB.getDate());
209                         buildup.insert(password);
210                         int memid = buildup.getId();
211                         PreparedStatement ps = DatabaseConnection.getInstance().prepare(
212                                 "insert into `email` set `email`=?," + " `hash`=?, `created`=NOW(),`memid`=?");
213                         ps.setString(1, buildup.getEmail());
214                         ps.setString(2, hash);
215                         ps.setInt(3, memid);
216                         ps.execute();
217                         int emailid = DatabaseConnection.lastInsertId(ps);
218                         ps = DatabaseConnection.getInstance().prepare(
219                                 "insert into `alerts` set `memid`=?," + " `general`=?, `country`=?, `regional`=?, `radius`=?");
220                         ps.setInt(1, memid);
221                         ps.setString(2, general ? "1" : "0");
222                         ps.setString(3, country ? "1" : "0");
223                         ps.setString(4, regional ? "1" : "0");
224                         ps.setString(5, radius ? "1" : "0");
225                         ps.execute();
226                         Notary.writeUserAgreement(memid, "CCA", "account creation", "", true, 0);
227
228                         StringBuffer body = new StringBuffer();
229                         body.append(Page
230                                 .translate(
231                                         req,
232                                         "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!"));
233                         body.append("\n\nhttps://");
234                         body.append(ServerConstants.getWwwHostNamePort());
235                         body.append("/verify?type=email&id=");
236                         body.append(emailid);
237                         body.append("&hash=");
238                         body.append(hash);
239                         body.append("\n\n");
240                         body.append(Page.translate(req, "Best regards"));
241                         body.append("\n");
242                         body.append(Page.translate(req, "CAcert.org Support!"));
243                         try {
244                                 EmailProvider.getInstance().sendmail(buildup.getEmail(),
245                                         "[CAcert.org] " + Page.translate(req, "Mail Probe"), body.toString(), "support@cacert.org", null,
246                                         null, null, null, false);
247                         } catch (IOException e) {
248                                 e.printStackTrace();
249                         }
250                         DatabaseConnection.getInstance().commitTransaction();
251                 } finally {
252                         DatabaseConnection.getInstance().quitTransaction();
253                 }
254
255         }
256 }