Mercurial Hosting > nabble
annotate src/nabble/view/web/more/ForumStart.jtp @ 36:157eac0dee34
whitelist for mailing lists
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 08 Jul 2020 12:22:41 -0600 |
parents | 61800d34be0d |
children | 40e282462f2e |
rev | line source |
---|---|
0 | 1 <% |
2 package nabble.view.web.more; | |
3 | |
4 import fschmidt.db.DbDatabase; | |
5 import fschmidt.util.mail.MailAddress; | |
6 import fschmidt.util.servlet.CanonicalUrl; | |
7 import nabble.model.Db; | |
8 import nabble.model.Message; | |
9 import nabble.model.ModelException; | |
10 import nabble.model.ModelHome; | |
11 import nabble.model.Site; | |
12 import nabble.model.User; | |
34 | 13 import nabble.model.Init; |
0 | 14 import nabble.naml.compiler.Template; |
15 import nabble.naml.compiler.TemplatePrintWriter; | |
16 import nabble.naml.namespaces.BasicNamespace; | |
17 import nabble.view.lib.Jtp; | |
18 import nabble.view.lib.NewSiteMail; | |
19 import nabble.view.lib.Permissions; | |
20 import nabble.view.lib.Shared; | |
21 import nabble.view.lib.UrlMappable; | |
22 import nabble.view.lib.Recaptcha; | |
23 import nabble.view.web.app.Languages; | |
24 import nabble.view.web.template.NabbleNamespace; | |
25 | |
26 import javax.servlet.ServletException; | |
27 import javax.servlet.http.HttpServlet; | |
28 import javax.servlet.http.HttpServletRequest; | |
29 import javax.servlet.http.HttpServletResponse; | |
30 import java.io.IOException; | |
31 import java.io.PrintWriter; | |
32 import java.io.StringWriter; | |
33 import java.util.Collections; | |
34 import java.util.HashMap; | |
35 import java.util.Map; | |
34 | 36 import java.util.Set; |
0 | 37 import java.util.regex.Matcher; |
38 import java.util.regex.Pattern; | |
28 | 39 import org.slf4j.Logger; |
40 import org.slf4j.LoggerFactory; | |
0 | 41 |
42 | |
43 public final class ForumStart extends HttpServlet implements UrlMappable, CanonicalUrl { | |
28 | 44 private static final Logger logger = LoggerFactory.getLogger(ForumStart.class); |
0 | 45 |
46 private static final Pattern URL_PATTERN = Pattern.compile("/free-(forum|gallery|newspaper|blog|mailing-list)\\.html$"); | |
47 | |
48 public static String url(String what) { | |
49 return Jtp.defaultContextUrl() + path(what); | |
50 } | |
51 | |
52 public static String path(String what) { | |
53 return "/free-" + what + ".html"; | |
54 } | |
55 | |
56 public String getCanonicalUrl(HttpServletRequest request) { | |
57 return url( request.getParameter("what") ); | |
58 } | |
59 | |
60 public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) { | |
61 Matcher m = URL_PATTERN.matcher(mappedUrl); | |
62 if( !m.find() ) | |
63 throw new RuntimeException(); | |
64 Map<String,String[]> params = new HashMap<String,String[]>(); | |
65 String what = m.group(1); | |
66 params.put("what",new String[]{what}); | |
67 return params; | |
68 } | |
69 | |
70 public Pattern getUrlPattern() { | |
71 return URL_PATTERN; | |
72 } | |
73 | |
74 protected void service(HttpServletRequest request,HttpServletResponse response) | |
75 throws ServletException, IOException | |
76 { | |
77 build(request, response, Collections.<String,String>emptyMap(), Collections.<String,String>emptyMap()); | |
78 } | |
79 | |
80 private static void build(HttpServletRequest request,HttpServletResponse response, Map<String,String> values, Map<String,String> errors) | |
81 throws ServletException, IOException | |
82 { | |
83 PrintWriter out = response.getWriter(); | |
84 String what = request.getParameter("what"); | |
85 if (what == null) | |
86 what = "Forum"; | |
87 else if ("mailing-list".equals(what)) | |
88 what = "Mailing List"; | |
89 else | |
90 what = Jtp.capitalize(what); | |
91 | |
92 String imgName = what.toLowerCase(); | |
93 if ("Mailing List".equals(what)) | |
94 imgName = "mailing-list"; | |
95 | |
96 %> | |
97 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |
98 <html> | |
99 <head> | |
100 <% Shared.head(request,response); %> | |
101 <title>Nabble - Free <%=what%> Setup</title> | |
102 <meta name="robots" content="noindex"/> | |
103 <META NAME="description" CONTENT="Setting up a free <%=what.toLowerCase()%> on Nabble is quick and easy. Fill in one simple form and you are done."> | |
104 <META NAME="keywords" CONTENT="free <%=what.toLowerCase()%>, hosted <%=what.toLowerCase()%>, simple, embeddable <%=what.toLowerCase()%>, customizable"> | |
105 <style type="text/css"> | |
106 div.center-content { | |
32 | 107 margin: 0px auto; |
0 | 108 margin-bottom: 3em; |
109 } | |
110 td.column1 { | |
32 | 111 text-align: right; |
112 width: 7em; | |
113 white-space: nowrap; | |
0 | 114 } |
115 input[type=text],input[type=password] { | |
32 | 116 padding: .4em 0; |
0 | 117 } |
118 div.field-title { | |
32 | 119 margin-top: .3em; |
120 } | |
121 .important { | |
122 font-weight: bold; | |
0 | 123 } |
32 | 124 label { |
125 vertical-align: -15%; | |
126 } | |
127 #submit-btn { | |
128 padding: .5em .8em; | |
129 font-size: 110%; | |
130 font-weight: bold; | |
131 } | |
0 | 132 </style> |
133 <script type="text/javascript"> | |
134 | |
135 function singleFormSubmit(f) { | |
136 if (f.done) | |
137 return false; | |
138 f.done = true; | |
139 $('#submit-btn').hide(); | |
140 var $div = $('#wait-message'); | |
141 function loading1() { $div.fadeTo(300,0.3,loading2); }; | |
142 function loading2() { $div.fadeTo(300,1,loading1); }; | |
143 loading1(); | |
144 return true; | |
145 }; | |
32 | 146 |
0 | 147 </script> |
148 <%= Recaptcha.JS %> | |
149 </head> | |
150 <body style="text-align:center"> | |
151 <% Shared.minHeaderGlobal(request,response); %> | |
152 | |
153 <div class="center-content"> | |
154 <img src="/images/logo_nabble_home.png" border="0" alt="Nabble - free forums for everyone"/><br /> | |
155 <h1 style="color:#979797">Start Your <%=what%></h1> | |
156 | |
157 <% if (errors.size() > 0) { %> | |
158 <div class="error-message important" style="margin:1em;padding:.5em 0"> | |
159 <% String generic = errors.get("generic"); %> | |
160 <%=generic != null? generic : errors.size() > 0? "Please check the errors below" : ""%> | |
161 </div> | |
162 <% } %> | |
163 | |
164 <form action="/more/ForumStart$Save.jtp" method="post" accept-charset="UTF-8" onsubmit="return singleFormSubmit(this)"> | |
165 <input type="hidden" name="type" value="<%=what.toLowerCase().replace(" ","")%>" /> | |
166 <input type="hidden" name="what" value="<%=what%>" /> | |
167 | |
168 <div style="text-align:left;width:50em;margin:0 auto"> | |
169 <div style="border-bottom:2px solid #eeeeee;padding:1em"> | |
170 <div class="weak-color" style="width:12em;text-align:center;float:left"> | |
171 <div style="font-weight:bold">Account</div> | |
172 <img src="/images/account.png" width="84" height="45"/> | |
173 <div style="margin-top:1em;font-size:80%"> | |
174 You will receive an email with a link to activate your account | |
175 </div> | |
176 </div> | |
177 <table> | |
178 <tr> | |
179 <td class="column1"><div class="second-font field-title">User Name</div></td> | |
32 | 180 <td><input type="text" autofocus size="35" maxlength="30" name="username" value="<%=Jtp.hideNull(values.get("username"))%>" /></td> |
0 | 181 <td class="important"><%=errors.containsKey("username")? errors.get("username"):""%></td> |
182 </tr> | |
183 <tr> | |
184 <td class="column1"><div class="second-font field-title">Email</div></td> | |
185 <td><input type="text" size="35" maxlength="60" name="email" value="<%=Jtp.hideNull(values.get("email"))%>"/></td> | |
186 <td class="important"><%=errors.containsKey("email")? errors.get("email"):""%></td> | |
187 </tr> | |
188 <tr> | |
189 <td class="column1"><div class="second-font field-title">Password</div></td> | |
190 <td><input type="password" size="35" maxlength="15" name="password" value="<%=Jtp.hideNull(values.get("password"))%>"/></td> | |
191 <td class="important"><%=errors.containsKey("password")? errors.get("password"):""%></td> | |
192 </tr> | |
193 <tr> | |
194 <td class="column1"><input type="checkbox" id="terms" name="terms" value="y" <%="y".equals(values.get("terms"))?"checked":""%> /></td> | |
195 <td colspan=2><label for="terms">I have read and I agree to Nabble's <a href="<%=Jtp.termsUrl(true)%>">Terms of Use</a>.</label></td> | |
196 </tr> | |
197 </table> | |
198 </div> | |
199 | |
200 <div style="padding:1em;overflow:hidden"> | |
201 <div class="weak-color" style="width:12em;text-align:center;float:left;height:15em"> | |
202 <div style="font-weight:bold"><%=what%></div> | |
203 <img src="/images/homepage/<%=imgName%>.png" alt="Free <%=what.toLowerCase()%>"> | |
204 </div> | |
205 <table> | |
206 <tr> | |
207 <td class="column1"><div class="second-font field-title">Language</div></td> | |
208 <td> | |
209 <select name="lang"> | |
210 <% for( Map.Entry<String,String> entry : Languages.languages.entrySet() ) { %> | |
211 <% String lang = request.getParameter("lang"); %> | |
212 <% boolean isEnglish = entry.getKey().equals("none"); %> | |
213 <% boolean isSelected = (lang == null && isEnglish) || entry.getKey().equals(lang); %> | |
214 <option value="<%=entry.getKey()%>" <%=isSelected?"selected=\"true\"":""%>><%=entry.getValue()%></option> | |
215 <% } %> | |
216 </select> | |
217 </td> | |
218 <td></td> | |
219 </tr> | |
220 <tr> | |
221 <td colspan="3" style="height:.6em"></td> | |
222 </tr> | |
223 <tr> | |
224 <td class="column1"><div class="second-font field-title"><%=what%> Name</div></td> | |
225 <td><input type="text" name="subject" size="30" maxlength="80" value="<%=Jtp.hideNull(values.get("subject"))%>"/></td> | |
226 <td class="important"><%=errors.containsKey("subject")? errors.get("subject"):""%></td> | |
227 </tr> | |
228 <tr> | |
229 <td colspan=3 style="padding:.4em 0 0 .6em"> | |
230 <div class="second-font field-title">Description <span class="weak-color" style="font-weight:normal;">(optional)</span></div> | |
231 <textarea rows="7" name="message" wrap="SOFT" style="width:28em"><%=Jtp.hideNull(values.get("message"))%></textarea> | |
232 <br><%= Recaptcha.DIV %> | |
233 </td> | |
234 </tr> | |
235 </table> | |
236 </div> | |
237 <div class="weak-color" style="margin-top:.5em;text-align:center;"> | |
32 | 238 <input id="submit-btn" type="submit" value="Create <%=what%>" /> |
0 | 239 <div id="wait-message" class="important invisible" style="margin:.1em 0">Creating <%=what%>... Please wait</div> |
240 </div> | |
241 </div> | |
242 </form> | |
243 </div> | |
244 | |
245 <% Shared.footer(request,response); %> | |
246 <% Shared.analytics(request,response); %> | |
247 </body> | |
248 </html> | |
249 <% | |
250 } | |
251 | |
28 | 252 |
36
157eac0dee34
whitelist for mailing lists
Franklin Schmidt <fschmidt@gmail.com>
parents:
34
diff
changeset
|
253 static final Set whitelist = (Set)Init.get("whitelist"); |
34 | 254 |
0 | 255 public static class Save extends HttpServlet { |
256 | |
257 private static String get(String name, HttpServletRequest request) { | |
258 String s = request.getParameter(name); | |
28 | 259 return s == null ? null : s.trim(); |
0 | 260 } |
261 | |
262 protected void service(HttpServletRequest request, HttpServletResponse response) | |
263 throws ServletException, IOException | |
264 { | |
265 String username = get("username", request); | |
266 String email = get("email", request); | |
267 String password = get("password", request); | |
268 boolean agreed = "y".equals(get("terms", request)); | |
269 String subject = get("subject", request); | |
270 String message = get("message", request); | |
271 | |
272 Map<String,String> errors = new HashMap<String,String>(); | |
273 if (username == null || username.trim().length() == 0) | |
274 errors.put("username", "required"); | |
275 if (email == null || email.length() == 0) | |
276 errors.put("email", "required"); | |
277 else if (!new MailAddress(email).isValid()) | |
278 errors.put("email", "invalid email"); | |
279 if (password == null || password.length() < 4) | |
280 errors.put("password", "too short"); | |
281 if (!agreed) | |
282 errors.put("generic", "You must agree to the Terms and Conditions"); | |
283 if (subject == null || subject.length() == 0) | |
284 errors.put("subject", "required"); | |
285 | |
286 String type = get("type", request); | |
287 type = "newspaper".equals(type)? "news" : type; | |
288 | |
289 String extraMessage = ""; | |
290 if ("mailinglist".equals(type)) { | |
291 type = "forum"; | |
292 StringBuilder m = new StringBuilder(); | |
293 m.append("\n\nMailing List Options\n"); | |
294 m.append("Click \"Options > Subscribe via email\" to subscribe to this mailing list;\n"); | |
295 m.append("Click \"Options > Post by email...\" to get the email address of this mailing list;\n"); | |
296 m.append("You can post messages via email or through the forum interface below;\n"); | |
297 m.append("All web posts and emails are archived here."); | |
298 extraMessage = m.toString(); | |
299 } | |
300 | |
301 if (errors.isEmpty()) { | |
34 | 302 if( whitelist!=null && !whitelist.contains(email) ) { |
303 logger.info("ignoring "+email); | |
304 return; | |
305 } | |
306 | |
0 | 307 DbDatabase db = Db.dbGlobal(); |
308 db.beginTransaction(); | |
309 try { | |
310 Recaptcha.check(request); | |
311 Site site = ModelHome.newSite(type,subject, message + extraMessage, Message.Format.TEXT, email, username); | |
312 Permissions.addToGroup( (User)site.getRootNode().getOwner(), Permissions.ADMINISTRATORS_GROUP ); | |
313 String key = site.newRegistration(email,password,username,"/"); | |
314 db.commitTransaction(); | |
315 | |
316 // Track spam activities by IP | |
317 ModelHome.setRemoteAddr(site, Jtp.getClientIpAddr(request)); | |
318 | |
319 site = site.getGoodCopy(); | |
320 | |
321 String lang = request.getParameter("lang"); | |
322 if (!"none".equals(lang)) { | |
323 site.setModuleEnabled(lang, true); | |
324 site = site.getGoodCopy(); | |
325 } | |
326 | |
327 sendRegisterMail(site, email, key); | |
328 NewSiteMail.send(site, request, response); | |
329 response.sendRedirect(site.getBaseUrl()+"/more/ForumStart$Redirection.jtp"); | |
330 return; | |
331 } catch(ModelException e) { | |
332 errors.put("generic", e.getMessage()); | |
333 } finally { | |
334 db.endTransaction(); | |
335 } | |
336 } | |
337 | |
338 Map<String,String> values = new HashMap<String,String>(); | |
339 values.put("username", username); | |
340 values.put("email", email); | |
341 values.put("password", password); | |
342 values.put("terms", agreed?"y":""); | |
343 values.put("subject", subject); | |
344 values.put("message", message); | |
345 build(request, response, values, errors); | |
346 } | |
347 } | |
348 | |
349 /** Sets cookies in the site domain */ | |
350 public static class Redirection extends HttpServlet { | |
351 | |
352 protected void service(HttpServletRequest request, HttpServletResponse response) | |
353 throws ServletException, IOException | |
354 { | |
355 Site site = Jtp.getSite(request); | |
356 Shared.javascriptRedirect(request, response, Jtp.url(site.getRootNode()), "Nabble.setVar('appnotice','true');"); | |
357 } | |
358 } | |
359 | |
360 public static void sendRegisterMail(Site site, String email, String key) { | |
361 Map<String,Object> args = new HashMap<String,Object>(); | |
362 args.put("email",email); | |
363 args.put("next_url","/"); | |
364 args.put("key",key); | |
365 Template template = site.getTemplate( "send_registration_email", | |
366 BasicNamespace.class, NabbleNamespace.class | |
367 ); | |
368 template.run( TemplatePrintWriter.NULL, args, | |
369 new BasicNamespace(template), new NabbleNamespace(site) | |
370 ); | |
371 } | |
372 } | |
373 %> |