comparison src/nabble/view/web/tools/SpamRules.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1
2 package nabble.view.web.tools;
3
4 import nabble.model.DailyNumber;
5 import nabble.model.ModelException;
6 import nabble.model.Person;
7 import nabble.model.SystemProperties;
8 import nabble.model.User;
9 import nabble.view.lib.Jtp;
10 import nabble.view.lib.Shared;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 import javax.servlet.ServletException;
15 import javax.servlet.http.HttpServlet;
16 import javax.servlet.http.HttpServletRequest;
17 import javax.servlet.http.HttpServletResponse;
18 import java.io.IOException;
19 import java.io.PrintWriter;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.regex.Pattern;
23
24
25 public final class SpamRules extends HttpServlet {
26
27 private static final Logger logger = LoggerFactory.getLogger(SpamRules.class);
28
29 private static final List<Rule> RULES = new ArrayList<Rule>();
30
31 static {
32 String spamRules = SystemProperties.get("spam.rules");
33 if (spamRules != null)
34 RULES.addAll(parseRules(spamRules));
35 }
36
37 private interface Rule {
38 public String checkSubject(String subject) throws ModelException.SpamException;
39 public String checkMessage(String message, Person visitor) throws ModelException.SpamException;
40 }
41 /*
42 public static void checkSubject(HttpServletRequest request, String subject)
43 throws ModelException.SpamException
44 {
45 if (subject == null)
46 return;
47
48 // Removes duplicated space chars
49 subject = subject.replaceAll("[ ]+"," ");
50 for (Rule rule : RULES) {
51 try {
52 rule.checkSubject(subject);
53 } catch (ModelException.SpamException e) {
54 DailyNumber.blockedSpams.inc();
55 if (request != null)
56 logger.info("host="+request.getServerName()+" | IP=" + Jtp.getClientIpAddr(request) + " | " + e.getMessage());
57 else
58 logger.info("Blocked Mail | " + e.getMessage());
59 throw e;
60 }
61 }
62 }
63
64 public static void checkMessage(HttpServletRequest request, String message, Person visitor)
65 throws ModelException.SpamException
66 {
67 if (message == null)
68 return;
69
70 // Removes duplicated space chars
71 message = message.replaceAll("[ ]+"," ");
72 for (Rule rule : RULES) {
73 try {
74 rule.checkMessage(message, visitor);
75 } catch (ModelException.SpamException e) {
76 DailyNumber.blockedSpams.inc();
77 String email = visitor instanceof User? ((User) visitor).getEmail() : "NO EMAIL";
78 if (request != null)
79 logger.info("host="+request.getServerName()+" | IP=" + Jtp.getClientIpAddr(request) + " | " + email + " | " + e.getMessage());
80 else
81 logger.info("Blocked Mail | " + email + " | " + e.getMessage());
82 throw e;
83 }
84 }
85 }
86 */
87 protected void service(HttpServletRequest request,HttpServletResponse response)
88 throws ServletException, IOException
89 {
90 String spamRules = SystemProperties.get("spam.rules");
91
92 if ("save".equals(request.getParameter("action"))) {
93 String rules = request.getParameter("rules");
94 RULES.clear();
95 if (rules != null && rules.length() > 0) {
96 List<Rule> r = parseRules(rules);
97 if (r.size() > 0)
98 RULES.addAll(r);
99 }
100 SystemProperties.set("spam.rules", rules);
101 response.sendRedirect("/tools/");
102 return;
103 }
104
105 PrintWriter out = response.getWriter();
106
107 out.print( "\n<html>\n <head>\n <script src=\"" );
108 out.print( (Shared.getJQueryPath()) );
109 out.print( "\"></script>\n <link rel=\"stylesheet\" href=\"" );
110 out.print( (Shared.getCssPath()) );
111 out.print( "\" type=\"text/css\" />\n </head>\n <body>\n <div>\n <a href=\"/tools/\">Tools</a>\n </div>\n <h1>Spam Rules</h1>\n <div id=\"nabble\" class=\"nabble\">\n <form action=\"/tools/SpamRules.jtp\" method=\"POST\">\n <input type=\"hidden\" name=\"action\" value=\"save\">\n <textarea name=\"rules\" rows=15 style=\"width:80%\">" );
112 out.print( (Jtp.hideNull(spamRules)) );
113 out.print( "</textarea>\n <br>\n <input type=\"submit\" value=\"Save Rules\">\n </form>\n </div>\n </body>\n</html>\n" );
114
115 }
116
117 private static synchronized List<Rule> parseRules(String rules) {
118 List<Rule> r = new ArrayList<Rule>();
119 String[] lines = rules.split("\n");
120 for (String line : lines) {
121 if (line.length() == 0 || line.startsWith("#")) {
122 // do nothing
123 } else if (line.startsWith("subject-contains:"))
124 r.add(new SubjectContainsRule(line.substring("subject-contains:".length()).trim()));
125 else if (line.startsWith("message-contains:"))
126 r.add(new MessageContainsRule(line.substring("message-contains:".length()).trim()));
127 else if (line.startsWith("message-contains-pattern:"))
128 r.add(new MessageContainsPattern(line.substring("message-contains-pattern:".length()).trim()));
129 else if (line.startsWith("message-word-count:"))
130 r.add(new WordCountRule(line.substring("message-word-count:".length()).trim()));
131 else if (line.startsWith("subject-max-words:"))
132 r.add(new SubjectMaxWordsRule(line.substring("subject-max-words:".length()).trim()));
133 else if (line.startsWith("message-max-words:"))
134 r.add(new MessageMaxWordsRule(line.substring("message-max-words:".length()).trim()));
135 else if (line.startsWith("user-email-pattern:"))
136 r.add(new UserEmailPattern(line.substring("user-email-pattern:".length()).trim()));
137 }
138 return r;
139 }
140
141 private static class SubjectContainsRule implements Rule {
142 private String text;
143 private String[] parts;
144 public SubjectContainsRule(String text) {
145 this.text = text;
146 this.parts = text.toLowerCase().split("\\+");
147 }
148 public String checkSubject(String subject)
149 throws ModelException.SpamException
150 {
151 if (subject == null) return null;
152 subject = subject.toLowerCase();
153 for (String part : parts) {
154 if (subject.indexOf(part) == -1)
155 return null;
156 }
157 throw new ModelException.SubjectContainsInvalidWord(text);
158 }
159 public String checkMessage(String message, Person visitor) { return null; }
160 }
161
162 private static class SubjectMaxWordsRule implements Rule {
163 private int max;
164 private String[] parts;
165 public SubjectMaxWordsRule(String text) {
166 String[] params = text.split("\\|");
167 this.max = Integer.valueOf(params[0]);
168 this.parts = params[1].toLowerCase().split("\\+");
169 }
170 public String checkSubject(String subject)
171 throws ModelException.SpamException
172 {
173 if (subject == null) return null;
174 subject = subject.toLowerCase();
175 int count = 0;
176 for (String part : parts) {
177 if (subject.indexOf(part) >= 0)
178 count++;
179 if (count >= max)
180 throw new ModelException.SubjectContainsCommonSpamWords(subject);
181 }
182 return null;
183 }
184 public String checkMessage(String message, Person visitor) { return null; }
185 }
186
187 private static class MessageMaxWordsRule implements Rule {
188 private int max;
189 private String[] parts;
190 public MessageMaxWordsRule(String text) {
191 String[] params = text.split("\\|");
192 this.max = Integer.valueOf(params[0]);
193 this.parts = params[1].toLowerCase().split("\\+");
194 }
195 public String checkMessage(String message, Person visitor)
196 throws ModelException.SpamException
197 {
198 if (message == null) return null;
199 message = message.toLowerCase();
200 int count = 0;
201 for (String part : parts) {
202 if (message.indexOf(part) >= 0)
203 count++;
204 if (count >= max)
205 throw new ModelException.MessageContainsCommonSpamWords(message);
206 }
207 return null;
208 }
209 public String checkSubject(String subject) { return null; }
210 }
211
212 private static class MessageContainsRule implements Rule {
213 private String text;
214 private String[] parts;
215 public MessageContainsRule(String text) {
216 this.text = text;
217 this.parts = text.toLowerCase().split("\\+");
218 }
219 public String checkMessage(String message, Person visitor)
220 throws ModelException.SpamException
221 {
222 if (message == null) return null;
223 String msg = message.toLowerCase();
224 for (String part : parts) {
225 if (msg.indexOf(part) == -1)
226 return null;
227 }
228 throw new ModelException.MessageContainsInvalidWord(text);
229 }
230 public String checkSubject(String subject) { return null; }
231 }
232
233 private static class MessageContainsPattern implements Rule {
234 private Pattern[] pattern;
235 public MessageContainsPattern(String patternList) {
236 String[] patterns = patternList.split("____");
237 this.pattern = new Pattern[patterns.length];
238 for (int i = 0; i < patterns.length; i++)
239 this.pattern[i] = Pattern.compile(patterns[i]);
240 }
241 public String checkMessage(String message, Person visitor)
242 throws ModelException.SpamException
243 {
244 if (message == null) return null;
245 for (Pattern p : pattern) {
246 if (!p.matcher(message).find())
247 return null;
248 }
249 throw new ModelException.MessageContainsCommonSpamWords(message);
250 }
251 public String checkSubject(String subject) { return null; }
252 }
253
254 private static class UserEmailPattern implements Rule {
255 private Pattern pattern;
256 public UserEmailPattern(String pattern) {
257 this.pattern = Pattern.compile(pattern);
258 }
259 public String checkMessage(String message, Person visitor)
260 throws ModelException.SpamException
261 {
262 if (visitor instanceof User) {
263 String email = ((User) visitor).getEmail();
264 if (!pattern.matcher(email).matches())
265 return null;
266 throw new ModelException.MessageContainsInvalidWord("EMAIL: " + email);
267 }
268 return null;
269 }
270 public String checkSubject(String subject) { return null; }
271 }
272
273 private static class WordCountRule implements Rule {
274 private String text;
275 private int count;
276 public WordCountRule(String value) {
277 String[] values = value.split(">");
278 this.text = values[0].toLowerCase();
279 this.count = Integer.valueOf(values[1]);
280 }
281 public String checkMessage(String message, Person visitor)
282 throws ModelException.SpamException
283 {
284 if (message == null) return null;
285 String msg = message.toLowerCase();
286 int oldPos = 0;
287 int newPos = msg.indexOf(text);
288 int c = 0;
289 while (newPos > oldPos) {
290 c++;
291 if (c >= count)
292 throw new ModelException.MessageContainsManyInvalidWords(text);
293 oldPos = newPos;
294 newPos = msg.indexOf(text, oldPos+text.length());
295 }
296 return null;
297 }
298 public String checkSubject(String subject) { return null; }
299 }
300 }
301