diff src/nabble/view/web/tools/SpamRules.jtp @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/view/web/tools/SpamRules.jtp	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,314 @@
+<%
+package nabble.view.web.tools;
+
+import nabble.model.DailyNumber;
+import nabble.model.ModelException;
+import nabble.model.Person;
+import nabble.model.SystemProperties;
+import nabble.model.User;
+import nabble.view.lib.Jtp;
+import nabble.view.lib.Shared;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+
+public final class SpamRules extends HttpServlet {
+
+	private static final Logger logger = LoggerFactory.getLogger(SpamRules.class);
+
+	private static final List<Rule> RULES = new ArrayList<Rule>();
+
+	static {
+		String spamRules = SystemProperties.get("spam.rules");
+		if (spamRules != null)
+			RULES.addAll(parseRules(spamRules));
+	}
+
+	private interface Rule {
+		public String checkSubject(String subject) throws ModelException.SpamException;
+		public String checkMessage(String message, Person visitor) throws ModelException.SpamException;
+	}
+/*
+	public static void checkSubject(HttpServletRequest request, String subject)
+		throws ModelException.SpamException
+	{
+		if (subject == null)
+			return;
+
+		// Removes duplicated space chars
+		subject = subject.replaceAll("[ ]+"," ");
+		for (Rule rule : RULES) {
+			try {
+				rule.checkSubject(subject);
+			} catch (ModelException.SpamException e) {
+				DailyNumber.blockedSpams.inc();
+				if (request != null)
+					logger.info("host="+request.getServerName()+" | IP=" + Jtp.getClientIpAddr(request) + " | " + e.getMessage());
+				else
+					logger.info("Blocked Mail | " + e.getMessage());
+				throw e;
+			}
+		}
+	}
+
+	public static void checkMessage(HttpServletRequest request, String message, Person visitor)
+		throws ModelException.SpamException
+	{
+		if (message == null)
+			return;
+
+		// Removes duplicated space chars
+		message = message.replaceAll("[ ]+"," ");
+		for (Rule rule : RULES) {
+			try {
+				rule.checkMessage(message, visitor);
+			} catch (ModelException.SpamException e) {
+				DailyNumber.blockedSpams.inc();
+				String email = visitor instanceof User? ((User) visitor).getEmail() : "NO EMAIL";
+				if (request != null)
+					logger.info("host="+request.getServerName()+" | IP=" + Jtp.getClientIpAddr(request) + " | " + email + " | " + e.getMessage());
+				else
+					logger.info("Blocked Mail | " + email + " | " + e.getMessage());
+				throw e;
+			}
+		}
+	}
+*/
+	protected void service(HttpServletRequest request,HttpServletResponse response)
+		throws ServletException, IOException
+	{
+		String spamRules = SystemProperties.get("spam.rules");
+
+		if ("save".equals(request.getParameter("action"))) {
+			String rules = request.getParameter("rules");
+			RULES.clear();
+			if (rules != null && rules.length() > 0) {
+				List<Rule> r = parseRules(rules);
+				if (r.size() > 0)
+					RULES.addAll(r);
+			}
+			SystemProperties.set("spam.rules", rules);
+			response.sendRedirect("/tools/");
+			return;
+		}
+
+		PrintWriter out = response.getWriter();
+		%>
+		<html>
+			<head>
+				<script src="<%=Shared.getJQueryPath()%>"></script>
+				<link rel="stylesheet" href="<%=Shared.getCssPath()%>" type="text/css" />
+			</head>
+			<body>
+				<div>
+					<a href="/tools/">Tools</a>
+				</div>
+				<h1>Spam Rules</h1>
+				<div id="nabble" class="nabble">
+					<form action="/tools/SpamRules.jtp" method="POST">
+						<input type="hidden" name="action" value="save">
+						<textarea name="rules" rows=15 style="width:80%"><%=Jtp.hideNull(spamRules)%></textarea>
+						<br>
+						<input type="submit" value="Save Rules">
+					</form>
+				</div>
+			</body>
+		</html>
+		<%
+	}
+
+	private static synchronized List<Rule> parseRules(String rules) {
+		List<Rule> r = new ArrayList<Rule>();
+		String[] lines = rules.split("\n");
+		for (String line : lines) {
+			if (line.length() == 0 || line.startsWith("#")) {
+				// do nothing
+			} else if (line.startsWith("subject-contains:"))
+				r.add(new SubjectContainsRule(line.substring("subject-contains:".length()).trim()));
+			else if (line.startsWith("message-contains:"))
+				r.add(new MessageContainsRule(line.substring("message-contains:".length()).trim()));
+			else if (line.startsWith("message-contains-pattern:"))
+				r.add(new MessageContainsPattern(line.substring("message-contains-pattern:".length()).trim()));
+			else if (line.startsWith("message-word-count:"))
+				r.add(new WordCountRule(line.substring("message-word-count:".length()).trim()));
+			else if (line.startsWith("subject-max-words:"))
+				r.add(new SubjectMaxWordsRule(line.substring("subject-max-words:".length()).trim()));
+			else if (line.startsWith("message-max-words:"))
+				r.add(new MessageMaxWordsRule(line.substring("message-max-words:".length()).trim()));
+			else if (line.startsWith("user-email-pattern:"))
+				r.add(new UserEmailPattern(line.substring("user-email-pattern:".length()).trim()));
+		}
+		return r;
+	}
+
+	private static class SubjectContainsRule implements Rule {
+		private String text;
+		private String[] parts;
+		public SubjectContainsRule(String text) {
+			this.text = text;
+			this.parts = text.toLowerCase().split("\\+");
+		}
+		public String checkSubject(String subject)
+			throws ModelException.SpamException
+		{
+			if (subject == null) return null;
+			subject = subject.toLowerCase();
+			for (String part : parts) {
+				if (subject.indexOf(part) == -1)
+					return null;
+			}
+			throw new ModelException.SubjectContainsInvalidWord(text);
+		}
+		public String checkMessage(String message, Person visitor) { return null; }
+	}
+
+	private static class SubjectMaxWordsRule implements Rule {
+		private int max;
+		private String[] parts;
+		public SubjectMaxWordsRule(String text) {
+			String[] params = text.split("\\|");
+			this.max = Integer.valueOf(params[0]);
+			this.parts = params[1].toLowerCase().split("\\+");
+		}
+		public String checkSubject(String subject)
+			throws ModelException.SpamException
+		{
+			if (subject == null) return null;
+			subject = subject.toLowerCase();
+			int count = 0;
+			for (String part : parts) {
+				if (subject.indexOf(part) >= 0)
+					count++;
+				if (count >= max)
+					throw new ModelException.SubjectContainsCommonSpamWords(subject);
+			}
+			return null;
+		}
+		public String checkMessage(String message, Person visitor) { return null; }
+	}
+
+	private static class MessageMaxWordsRule implements Rule {
+		private int max;
+		private String[] parts;
+		public MessageMaxWordsRule(String text) {
+			String[] params = text.split("\\|");
+			this.max = Integer.valueOf(params[0]);
+			this.parts = params[1].toLowerCase().split("\\+");
+		}
+		public String checkMessage(String message, Person visitor)
+			throws ModelException.SpamException
+		{
+			if (message == null) return null;
+			message = message.toLowerCase();
+			int count = 0;
+			for (String part : parts) {
+				if (message.indexOf(part) >= 0)
+					count++;
+				if (count >= max)
+					throw new ModelException.MessageContainsCommonSpamWords(message);
+			}
+			return null;
+		}
+		public String checkSubject(String subject) { return null; }
+	}
+
+	private static class MessageContainsRule implements Rule {
+		private String text;
+		private String[] parts;
+		public MessageContainsRule(String text) {
+			this.text = text;
+			this.parts = text.toLowerCase().split("\\+");
+		}
+		public String checkMessage(String message, Person visitor)
+			throws ModelException.SpamException
+		{
+			if (message == null) return null;
+			String msg = message.toLowerCase();
+			for (String part : parts) {
+				if (msg.indexOf(part) == -1)
+					return null;
+			}
+			throw new ModelException.MessageContainsInvalidWord(text);
+		}
+		public String checkSubject(String subject) { return null; }
+	}
+
+	private static class MessageContainsPattern implements Rule {
+		private Pattern[] pattern;
+		public MessageContainsPattern(String patternList) {
+			String[] patterns = patternList.split("____");
+			this.pattern = new Pattern[patterns.length];
+			for (int i = 0; i < patterns.length; i++)
+				this.pattern[i] = Pattern.compile(patterns[i]);
+		}
+		public String checkMessage(String message, Person visitor)
+			throws ModelException.SpamException
+		{
+			if (message == null) return null;
+			for (Pattern p : pattern) {
+				if (!p.matcher(message).find())
+					return null;
+			}
+			throw new ModelException.MessageContainsCommonSpamWords(message);
+		}
+		public String checkSubject(String subject) { return null; }
+	}
+
+	private static class UserEmailPattern implements Rule {
+		private Pattern pattern;
+		public UserEmailPattern(String pattern) {
+			this.pattern = Pattern.compile(pattern);
+		}
+		public String checkMessage(String message, Person visitor)
+			throws ModelException.SpamException
+		{
+			if (visitor instanceof User) {
+				String email = ((User) visitor).getEmail();
+				if (!pattern.matcher(email).matches())
+					return null;
+				throw new ModelException.MessageContainsInvalidWord("EMAIL: " + email);
+			}
+			return null;
+		}
+		public String checkSubject(String subject) { return null; }
+	}
+
+	private static class WordCountRule implements Rule {
+		private String text;
+		private int count;
+		public WordCountRule(String value) {
+			String[] values = value.split(">");
+			this.text = values[0].toLowerCase();
+			this.count = Integer.valueOf(values[1]);
+		}
+		public String checkMessage(String message, Person visitor)
+			throws ModelException.SpamException
+		{
+			if (message == null) return null;
+			String msg = message.toLowerCase();
+			int oldPos = 0;
+			int newPos = msg.indexOf(text);
+			int c = 0;
+			while (newPos > oldPos) {
+				c++;
+				if (c >= count)
+					throw new ModelException.MessageContainsManyInvalidWords(text);
+				oldPos = newPos;
+				newPos = msg.indexOf(text, oldPos+text.length());
+			}
+			return null;
+		}
+		public String checkSubject(String subject) { return null; }
+	}
+}
+%>