diff src/nabble/view/web/forum/ChangeDomainName.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 18cf4872fd7f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/view/web/forum/ChangeDomainName.java	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,172 @@
+
+package nabble.view.web.forum;
+
+import fschmidt.util.mail.Mail;
+import fschmidt.util.mail.MailAddress;
+import fschmidt.util.mail.MailException;
+import fschmidt.util.mail.MailHome;
+import fschmidt.util.mail.PlainTextContent;
+import nabble.model.ModelException;
+import nabble.model.ModelHome;
+import nabble.model.Node;
+import nabble.model.Site;
+import nabble.model.User;
+import nabble.naml.namespaces.TemplateException;
+import nabble.view.lib.Jtp;
+import nabble.view.lib.Permissions;
+import nabble.view.lib.Shared;
+
+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.InetAddress;
+import java.net.UnknownHostException;
+
+
+public final class ChangeDomainName extends HttpServlet {
+
+	protected void service(HttpServletRequest request,HttpServletResponse response)
+		throws ServletException, IOException
+	{
+		Site site = ModelHome.getSite(Jtp.getLong(request, "site"));
+		if (site == null) {
+			response.sendError(HttpServletResponse.SC_NOT_FOUND, "No application match the \"<i>" + request.getHeader("host") + "</i>\" domain.");
+			return;
+		}
+
+		User user = Jtp.getUser(request, response);
+		if (user == null) {
+			response.sendRedirect("http://" + Jtp.getDefaultBaseUrl(site) + Jtp.loginPath(site,null,response.encodeURL("/forum/ChangeDomainName.jtp?site="+site.getId())) );
+			return;
+		}
+
+		boolean isSiteAdmin = Permissions.isInGroup(user, Permissions.ADMINISTRATORS_GROUP);
+		boolean isSysAdmin = Permissions.isSysAdmin(user);
+		if (!isSiteAdmin && !isSysAdmin) {
+			Jtp.login("Only administrators can proceed in this area.", request, response);
+			return;
+		}
+
+		Node rootNode = site.getRootNode();
+		boolean isSave = "save".equals(request.getParameter("action"));
+
+		String domainName = site.getCustomDomain();
+		String domainOption = domainName == null? "default-domain" : "own-domain";
+		if (isSave) {
+			domainName = request.getParameter("domain-name");
+			domainOption = request.getParameter("domain-option");
+		}
+
+		String errorMsg = null;
+		if (isSave && "POST".equals(request.getMethod())) {
+			try {
+				boolean isDefault = "default-domain".equals(domainOption);
+				if (isDefault)
+					site.setCustomDomain(null);
+				else {
+					domainName = domainName.trim();
+					if (domainName.length() == 0 || domainName.endsWith(".nabble.com") || domainName.equals(InetAddress.getLocalHost().getHostAddress()))
+						throw ModelException.newInstance("invalid_domain", "Please enter a valid domain name for your application.");
+					Long currentSiteId = ModelHome.getSiteIdFromDomain(domainName);
+					if (currentSiteId != null && !currentSiteId.equals(site.getId()))
+						throw ModelException.newInstance("domain_already_in_use", "This domain is already in use.");
+					String domainIP = getDomainIP(domainName);
+					String nabbleIP = getDomainIP(Jtp.getDefaultHost());
+					if (!nabbleIP.equals(domainIP))
+						throw ModelException.newInstance(
+							"domain_bad_resolution",
+							"Your domain name currently resolves to an IP address that doesn't belong to Nabble. " +
+							"Please follow the instructions (see link below) in order to update your DNS. " +
+							"If you have just updated your DNS, please wait 24 hours for the changes to take affect.");
+
+					site.setCustomDomain(domainName);
+				}
+				sendEmail(user, site);
+				response.sendRedirect(Jtp.url(rootNode));
+				return;
+			} catch (TemplateException e) {
+				errorMsg = e.getMessage();
+			}
+		}
+
+		PrintWriter out = response.getWriter();
+		
+		out.print( "\n<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n	<head>\n		<META NAME=\"robots\" CONTENT=\"noindex,nofollow\">\n		" );
+ Shared.title(request, response, "Change Domain Name"); 
+		out.print( "\n		<style type=\"text/css\">\n			label { font-weight:bold; }\n			.step {\n				font-weight: bold;\n				font-size: 120%;\n				padding: .5em .3em;\n				white-space:nowrap;\n			}\n		</style>\n		<script type=\"text/javascript\">\n			$(document).ready(function() {\n				function enableControls() {\n					if ($('#default-domain').attr('checked')) {\n						$('#domain-name').attr('disabled','y');\n					} else {\n						$('#domain-name').removeAttr('disabled').focus();\n					}\n				};\n				$('#default-domain,#own-domain').change(enableControls);\n				enableControls();\n			});\n		</script>\n	</head>\n	<body>\n		" );
+ Shared.minHeader(request,response, rootNode); 
+		out.print( "\n		" );
+ Shared.editHeader(rootNode.getSubjectHtml(), "Change Domain Name", out); 
+		out.print( "\n		" );
+ Shared.errorMessage(request, response, errorMsg, null); 
+		out.print( "\n\n		" );
+ if (site.getCustomDomain() != null) { 
+		out.print( "\n			<div class=\"info-message rounded\" style=\"padding: .5em;margin:.4em 0\">\n				<b>You already have a domain set for \"" );
+		out.print( (rootNode.getSubject()) );
+		out.print( "\".</b><br/>\n				If you change this domain configuration, links to the old domain will probably stop working.\n			</div>\n		" );
+ } 
+		out.print( "\n\n		<div class=\"field weak-color\" style=\"margin-left:1.5em\">\n			<div style=\"margin:1em 0 .5em\">\n				Access your application with a custom domain name.\n			</div>\n\n			<form method=\"post\" action=\"/forum/ChangeDomainName.jtp\" accept-charset=\"UTF-8\">\n				<input type=\"hidden\" name=\"action\" value=\"save\"/>\n				<input type=\"hidden\" name=\"site\" value=\"" );
+		out.print( (site.getId()) );
+		out.print( "\"/>\n				<input type=\"radio\" name=\"domain-option\" id=\"default-domain\" value=\"default-domain\" " );
+		out.print( ("default-domain".equals(domainOption)?"checked='y'":"") );
+		out.print( "/>\n				<label for=\"default-domain\">Nabble Default URL</label>\n				<div style=\"margin:.5em 0 1em 3em\">\n					http://" );
+		out.print( (Jtp.getDefaultBaseUrl(site)) );
+		out.print( "/\n				</div>\n\n				<input type=\"radio\" name=\"domain-option\" id=\"own-domain\" value=\"own-domain\" " );
+		out.print( ("own-domain".equals(domainOption)?"checked='y'":"") );
+		out.print( "/>\n				<label for=\"own-domain\">Your Own Domain</label>\n				<div style=\"margin:.5em 0 1em 3em\">\n					<table class=\"weak-color\">\n						<tr style=\"vertical-align:top\">\n							<td style=\"padding-right:.8em\"><div class=\"second-font shaded-bg-color rounded step border1 medium-border-color\">Step 1</div></td>\n							<td>\n								Go to your Domain Registrar and set the CNAME-record for your custom domain to <b>" );
+		out.print( (Jtp.getDefaultHost()) );
+		out.print( "</b>.\n								(<a href=\"/help/DNSConfiguration.jtp\" target=\"_new\">show me more details</a>)\n								<div style=\"margin-top:.7em;font-size:80%\">\n									(After this change, wait a little bit for the DNS to propagate.\n									Then open your custom domain url in the browser to see if the change is propagated &ndash; if successful, you should get redirected to the Nabble home page)\n								</div>\n							</td>\n						</tr>\n						<tr style=\"vertical-align:top\">\n							<td style=\"padding:1.7em .5em 0 0\"><div class=\"second-font shaded-bg-color rounded step border1 medium-border-color\">Step 2</div></td>\n							<td style=\"padding-top:1.5em\">\n								<div style=\"margin-bottom:.3em\">Enter your custom domain name below:</div>\n								http://<input id=\"domain-name\" name=\"domain-name\" size=\"40\" value=\"" );
+		out.print( (Jtp.hideNull(domainName)) );
+		out.print( "\"/>\n								<div style=\"font-size:80%;margin:.3em 0\">\n									Example: mydomain.com\n								</div>\n							</td>\n						</tr>\n						<tr style=\"vertical-align:top\">\n							<td style=\"padding:1.3em .5em 0 0\"><div class=\"second-font shaded-bg-color rounded step border1 medium-border-color\">Step 3</div></td>\n							<td style=\"padding-top:1.1em\">\n								After saving your changes, your old URLs will continue to work and will automatically redirect to your custom domain URL.\n								You will also receive an email with a link to revert this domain change.\n							</td>\n						</tr>\n					</table>\n				</div>\n\n				<input type=\"submit\" value=\"Save Changes\" />\n				or <a href=\"" );
+		out.print( (Jtp.path(rootNode)) );
+		out.print( "\">Cancel</a>\n			</form>\n		</div>\n		" );
+ Shared.footer(request, response); 
+		out.print( "\n		" );
+ Shared.analytics(request, response); 
+		out.print( "\n	</body>\n</html>\n" );
+
+	}
+
+	private static String getDomainIP(String domain) {
+		String ip = domain;
+		int i = ip.indexOf(":");
+		if( i > 0 )
+			ip = ip.substring(0,i);
+		try {
+			InetAddress add = InetAddress.getByName(ip);
+			if (add != null)
+				ip = add.getHostAddress();
+		} catch(UnknownHostException e) {}
+		return ip;
+	}
+
+	private static void sendEmail(User user, Site site)
+		throws IOException, ServletException
+	{
+		StringBuilder builder = new StringBuilder();
+		builder.append("Dear ").append(user.getName()).append(",\n\n");
+		builder.append("You have changed your domain name configuration to:\n");
+		builder.append(site.getBaseUrl());
+		builder.append("\n\n");
+		builder.append("If you have problems with your domain name or simply want to change this configuration again, you can use this link:\n");
+		builder.append("http://").append(Jtp.getDefaultHost()).append("/forum/ChangeDomainName.jtp?site=").append(site.getId());
+		builder.append("\n\n");
+		builder.append("Regards,\n");
+		builder.append("The Nabble team");
+
+		try {
+			Mail mail = MailHome.newMail();
+			mail.setFrom(new MailAddress(ModelHome.noReply, "Nabble"));
+			mail.setTo(new MailAddress(user.getEmail()));
+			mail.setSubject("Domain name configuration changed");
+			mail.setContent(new PlainTextContent(builder.toString()));
+			ModelHome.send(mail);
+		} catch(MailException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
+