view src/nabble/view/web/more/MailingListRequest.jtp @ 37:40e282462f2e

fixed password instead of whitelist
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 08 Jul 2020 21:05:15 -0600
parents 157eac0dee34
children
line wrap: on
line source

<%
package nabble.view.web.more;

import fschmidt.db.DbDatabase;
import fschmidt.util.mail.MailAddress;
import fschmidt.util.servlet.CanonicalUrl;
import nabble.model.Db;
import nabble.model.ListServer;
import nabble.model.MailingList;
import nabble.model.Message;
import nabble.model.ModelException;
import nabble.model.ModelHome;
import nabble.model.Node;
import nabble.model.Site;
import nabble.model.User;
import nabble.model.Init;
import nabble.view.lib.Jtp;
import nabble.view.lib.NewSiteMail;
import nabble.view.lib.Permissions;
import nabble.view.lib.Shared;
import nabble.view.lib.UrlMappable;
import nabble.view.lib.Recaptcha;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public final class MailingListRequest extends HttpServlet implements UrlMappable, CanonicalUrl {
	private static final Logger logger = LoggerFactory.getLogger(MailingListRequest.class);

	private static final Pattern URL_PATTERN = Pattern.compile("/archive-your-mailing-list\\.html$");

	public static String url() {
		return Jtp.defaultContextUrl() + path();
	}

	public static String path() {
		return "/archive-your-mailing-list.html";
	}

	public String getCanonicalUrl(HttpServletRequest request) {
		return url();
	}

	public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) {
		Matcher m = URL_PATTERN.matcher(mappedUrl);
		if( !m.find() )
			throw new RuntimeException();
		return new HashMap<String,String[]>();
	}

	public Pattern getUrlPattern() {
		return URL_PATTERN;
	}

	protected void service(HttpServletRequest request,HttpServletResponse response)
		throws ServletException, IOException
	{
		build(request, response, Collections.<String,String>emptyMap(), Collections.<String,String>emptyMap());
	}

	private static void build(HttpServletRequest request,HttpServletResponse response, Map<String,String> values, Map<String,String> errors)
		throws ServletException, IOException
	{
		PrintWriter out = response.getWriter();
		%>
		<html>
			<head>
				<% Shared.title(request,response,"Archive Your Mailing List"); %>
				<META NAME="description" CONTENT="Archiving a mailing list at Nabble is quick and easy. Fill in one simple form and you're done.">
				<META NAME="keywords" CONTENT="free, mailing list archive, forum interface, gateway, customizable, easy, quick setup">
				<style type="text/css">
					div.field-title {
						margin-top: 0;
					}
					td.column1 {
						text-align:right;
						width:7em;
						white-space:nowrap;
					}
					div.field-box {
						border:none;
						margin:0;
					}
					input[type=text],input[type=password],select {
                        padding:.3em 0;
                    }
					.important { font-weight:bold }
				</style>
				<script type="text/javascript">
					$(document).ready(function() {
						$('#username').focus();
					});
				</script>
				<%= Recaptcha.JS %>
			</head>
			<body>
				<% Shared.minHeaderGlobal(request,response); %>

				<h1>Archive Your Mailing List</h1>
				<p>
					<img src="/images/homepage/archive.png" style="float:left;margin: 0 1em 1em 1em"/>
					You can archive your mailing list to a fully functional forum at Nabble by filling out
					the form below.  This makes it easy for users to browse and search archived emails.
					Users can even post to the Nabble forum and we will forward these posts to your mailing list.
				</p>

				<% if (errors.size() > 0) { %>
					<div class="error-message important" style="margin:1em;padding:.5em 0 .5em 12em">
						<% String generic = errors.get("generic"); %>
						<%=generic != null? generic : errors.size() > 0? "Please check the errors below" : ""%>
					</div>
				<% } %>

				<form method="post" action="/more/MailingListRequest$Save.jtp" accept-charset="UTF-8">
					<input type="hidden" name="Action" value="save">

					<div style="border-bottom:2px solid #eeeeee;padding:1em;width:50em">
						<div class="weak-color" style="width:11.5em;text-align:center;float:left">
							<div style="font-weight:bold">Account</div>
							<img src="/images/account.png"/>
							<div style="margin-top:1em;font-size:80%">
								You will receive an email with a link to activate your account
							</div>
						</div>
						<table>
							<tr>
								<td><div class="second-font field-title">User Name</div></td>
								<td><input type="text" id="username" size="35" maxlength="30" name="username" value="<%=Jtp.hideNull(values.get("username"))%>" /></td>
								<td class="important"><%=errors.containsKey("username")? errors.get("username"):""%></td>
							</tr>
							<tr>
								<td><div class="second-font field-title">Email</div></td>
								<td><input type="text" size="35" maxlength="60" name="email" value="<%=Jtp.hideNull(values.get("email"))%>"/></td>
								<td class="important"><%=errors.containsKey("email")? errors.get("email"):""%></td>
							</tr>
							<tr>
								<td><div class="second-font field-title">Password</div></td>
								<td><input type="password" size="35" maxlength="15" name="password" value="<%=Jtp.hideNull(values.get("password"))%>"/></td>
								<td class="important"><%=errors.containsKey("password")? errors.get("password"):""%></td>
							</tr>
							<tr>
								<td class="column1"><input type="checkbox" id="terms" name="terms" value="y" <%="y".equals(values.get("terms"))?"checked":""%> /></td>
								<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>
							</tr>
						</table>
					</div>

					<div style="padding:.5em;width:50em">
						<div class="weak-color" style="width:12em;text-align:center;float:left;height:50em;padding-top:1em">
							<div style="font-weight:bold">Mailing List</div>
							<img src="/images/homepage/mailing-list.png" alt="Free Mailing List Archive">
						</div>

						<div class="field-box">
							<div class="second-font field-title">Mailing List Address</div>
							<div class="weak-color">
								<input id="mailingList" type="text" name="ml-address" value="<%=Jtp.hideNull(values.get("ml-address"))%>" size="46" />
								<span class="important"><%=errors.containsKey("ml-address")? errors.get("ml-address"):""%></span>
								<div class="weak-color">e.g., mygroup@yahoogroups.com</div>
							</div>
						</div>

						<div class="field-box light-border-color">
							<div class="second-font field-title">Mailing List URL</div>
							<div class="weak-color">
								Enter the homepage of this mailing list, where other users can find more information.<br/>
								<input type="text" name="ml-url" size="55" value="<%=Jtp.hideNull(values.get("ml-url"))%>" />
								<span class="important"><%=errors.containsKey("ml-url")? errors.get("ml-url"):""%></span>
								<div class="weak-color">e.g., http://www.mailinglist.com/list</div>
							</div>
						</div>

						<div class="field-box light-border-color">
							<div class="second-font field-title">Forum Name</div>
							<div class="weak-color">
								Enter the name of the forum for this mailing list.<br/>
								<input type="text" name="subject" size="46" value="<%=Jtp.hideNull(values.get("subject"))%>" />
								<span class="important"><%=errors.containsKey("subject")? errors.get("subject"):""%></span>
							</div>
						</div>

						<div class="field-box light-border-color">
							<div class="second-font field-title">Forum Description</div>
							<div class="weak-color">
								<textarea cols=46 rows=5 name="message" id="nabble.desc" wrap="SOFT"><%=Jtp.hideNull(values.get("message"))%></textarea>
							</div>
						</div>

						<div class="field-box light-border-color">
							<div class="second-font field-title">List Server and Version</div>
							<div class="weak-color">
								If you know, please select the mailing list server application.<br/>
								<select name="server-type">
									<%
									String[] serverTypes = ListServer.getAllServerTypes();
									ListServer selectedServer = ListServer.getServer(values.get("server-type"));
									for (String s : serverTypes) {
										ListServer currentServer = ListServer.getServer(s);
										if(currentServer.showInInitialSetup()) {
											%><option value="<%=currentServer.getType()%>" <%=currentServer == selectedServer?"selected":""%>><%=currentServer.getViewName()%></option><%
										}
									}
									%>
								</select>
								<div class="weak-color">If you are not absolutely sure about the version of the list server, it is better if you leave it as Unknown</div>
							</div>
						</div>

						<div class="field-box light-border-color">
							<div class="second-font field-title">Other Settings</div>
							<table>
								<tr>
									<td><input id="plain-text" name="plain-text" type="checkbox" value="y" <%="y".equals(values.get("plain-text"))?"checked":""%> /></td>
									<td><label for="plain-text">This list accepts only plain-text emails</label>.</td>
								</tr>
								<tr>
									<td><input id="ignore-x-noarchive" name="ignore-x-noarchive" type="checkbox" value="y" <%="y".equals(values.get("ignore-x-noarchive"))?"checked":""%> /></td>
									<td><label for="ignore-x-noarchive">Ignore X-No-Archive Header</label>.</td>
								</tr>
								<tr>
									<td colspan=2 style="padding-top:1em">
										<%= Recaptcha.DIV %>
									</td>
								</tr>
							</table>
						</div>

						<input type="submit" value="Create Mailing List Archive" style="padding:.5em .8em;font-size:110%;font-weight:bold"/>
					</div>
				</form>

				<% Shared.footer(request,response); %>
				<% Shared.analytics(request,response); %>
			</body>
		</html>
		<%
	}

	private static final String newSitePassword = (String)Init.get("new_site_password");

	public static class Save extends HttpServlet {

		private static String get(String name, HttpServletRequest request) {
			String s = request.getParameter(name);
			return s == null? null : s.trim();
		}

		protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException
		{
			String username = get("username", request);
			String email = get("email", request);
			String password = get("password", request);
			boolean agreed = "y".equals(get("terms", request));

			String mlAddress = get("ml-address", request);
			String mlUrl = get("ml-url", request);
			String subject = get("subject", request);
			String message = get("message", request);
			String serverType = get("server-type", request);
			boolean isPlainText = "y".equals(get("plain-text", request));
			boolean isIgnoreXNoArchive = "y".equals(get("ignore-x-noarchive", request));

			Map<String,String> errors = new HashMap<String,String>();
			if (username == null || username.trim().length() == 0)
				errors.put("username", "required");
			if (email == null || email.length() == 0)
				errors.put("email", "required");
			else if (!new MailAddress(email).isValid())
				errors.put("email", "invalid email");
			if (password == null || password.length() < 4)
				errors.put("password", "too short");
			if (!agreed)
				errors.put("generic", "You must agree to the Terms and Conditions");
			if (subject == null || subject.length() == 0)
				errors.put("subject", "required");
			if (mlAddress == null || mlAddress.length() == 0)
				errors.put("ml-address", "required");
			else if (!new MailAddress(mlAddress).isValid())
				errors.put("ml-address", "invalid email");
			if (mlUrl == null || mlUrl.length() == 0)
				errors.put("ml-url", "required");
			else {
				try {
					new URL(mlUrl);
				} catch (MalformedURLException e) {
					errors.put("ml-url", "invalid URL");
				}
			}

			if (errors.isEmpty()) {
				if( newSitePassword!=null && !newSitePassword.equals(password) ) {
					logger.info("ignoring "+email);
					return;
				}

				DbDatabase db = Db.dbGlobal();
				db.beginTransaction();
				try {
					Recaptcha.check(request);
					Site site = ModelHome.newSite(Node.Type.FORUM,subject, message, Message.Format.TEXT, email, username);
					Permissions.addToGroup( (User)site.getRootNode().getOwner(), Permissions.ADMINISTRATORS_GROUP );
					String key = site.newRegistration(email,password,username,"/mailing_list/SubscribeToMailingList.jtp?node="+site.getRootNode().getId());

					MailingList ml = site.getRootNode().newMailingList(ListServer.getServer(serverType), mlAddress, mlUrl);
					ml.setPlainTextOnly(isPlainText);
					ml.setIgnoreNoArchive(isIgnoreXNoArchive);
					ml.update();

					db.commitTransaction();

					site = site.getGoodCopy();
					ForumStart.sendRegisterMail(site, email, key);
					NewSiteMail.send(site, request, response);
					response.sendRedirect(site.getBaseUrl()+"/more/MailingListRequest$FinalSteps.jtp");
					return;
				} catch(ModelException e) {
					errors.put("generic", e.getMessage());
				} finally {
					db.endTransaction();
				}
			}

			Map<String,String> values = new HashMap<String,String>();
			values.put("username", username);
			values.put("email", email);
			values.put("password", password);
			values.put("terms", agreed?"y":"");

			values.put("ml-address", mlAddress);
			values.put("ml-url", mlUrl);
			values.put("subject", subject);
			values.put("message", message);
			values.put("server-type", serverType);
			values.put("plain-text", isPlainText?"y":"");
			values.put("ignore-x-noarchive", isIgnoreXNoArchive?"y":"");
			build(request, response, values, errors);
		}
	}

	public static class FinalSteps extends HttpServlet {

		protected void service(HttpServletRequest request, HttpServletResponse response)
				throws ServletException, IOException
		{
			PrintWriter out = response.getWriter();
			%>
			<html>
				<head>
					<% Shared.title(request,response,"Archive Created, But Subscription is Needed"); %>
				</head>
				<body>
					<% Shared.minHeaderGlobal(request,response); %>
					<h1>Success</h1>
					<p>Your mailing list archive has been successfully created.</p>
					<h2>What should I do now?</h2>
					<p>
						You should now check your email and click on the activation link sent to you.
						That link will complete your account registration and take you to the page where you can subscribe the Nabble archive to the mailing list.
						<b>If you don't subscribe the archive to the mailing list, it will NOT work properly!</b>
					</p>
					<p>You can contact <a href="<%=Jtp.supportUrl()%>">Nabble Support</a> if you have questions.</p>
					<% Shared.footer(request,response); %>
					<% Shared.analytics(request,response); %>
				</body>
			</html>
			<%
		}
	}
}
%>