Mercurial Hosting > nabble
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; } + } +} +%>