KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > messenger > plugin > ContentFilterPlugin


1 /**
2  * $RCSfile: ContentFilterPlugin.java,v $
3  * $Revision: 1.1 $
4  * $Date: 2005/07/04 17:08:41 $
5  *
6  * Copyright (C) 2004 Jive Software. All rights reserved.
7  *
8  * This software is published under the terms of the GNU Public License (GPL),
9  * a copy of which is included in this distribution.
10  */

11
12 package org.jivesoftware.messenger.plugin;
13
14 import org.jivesoftware.messenger.MessageRouter;
15 import org.jivesoftware.messenger.Session;
16 import org.jivesoftware.messenger.XMPPServer;
17 import org.jivesoftware.messenger.container.Plugin;
18 import org.jivesoftware.messenger.container.PluginManager;
19 import org.jivesoftware.messenger.interceptor.InterceptorManager;
20 import org.jivesoftware.messenger.interceptor.PacketInterceptor;
21 import org.jivesoftware.messenger.interceptor.PacketRejectedException;
22 import org.jivesoftware.util.JiveGlobals;
23 import org.xmpp.packet.JID;
24 import org.xmpp.packet.Message;
25 import org.xmpp.packet.Packet;
26
27 import java.io.File JavaDoc;
28
29 /**
30  * Content filter plugin.
31  *
32  * @author Conor Hayes
33  */

34 public class ContentFilterPlugin implements Plugin, PacketInterceptor {
35
36     /**
37      * The expected value is a boolean, if true the user identified by the value
38      * of the property #VIOLATION_NOTIFICATION_CONTACT_PROPERTY will be notified
39      * every time there is a content match, otherwise no notification will be
40      * sent. Then default value is false.
41      */

42     public static final String JavaDoc VIOLATION_NOTIFICATION_ENABLED_PROPERTY =
43             "plugin.contentFilter.violation.notification.enabled";
44
45     /**
46      * The expected value is a user name. The default value is "admin".
47      */

48     public static final String JavaDoc VIOLATION_NOTIFICATION_CONTACT_PROPERTY =
49             "plugin.contentFilter.violation.notification.contact";
50
51     /**
52      * The expected value is a boolean, if true the sender will be notified when a
53      * message is rejected, otherwise the message will be silently rejected,i.e. the
54      * sender will not know that the message was rejected and the receiver will
55      * not get the message. The default value is false.
56      */

57     public static final String JavaDoc REJECTION_NOTIFICATION_ENABLED_PROPERTY =
58             "plugin.contentFilter.rejection.notification.enabled";
59
60     /**
61      * The expected value is a string, containing the desired message for the
62      * sender notification.
63      */

64     public static final String JavaDoc REJECTION_MSG_PROPERTY = "plugin.contentFilter.rejection.msg";
65
66     /**
67      * The expected value is a boolean, if true the value of #PATTERNS_PROPERTY
68      * will be used for pattern matching.
69      */

70     public static final String JavaDoc PATTERNS_ENABLED_PROPERTY = "plugin.contentFilter.patterns.enabled";
71
72     /**
73      * The expected value is a comma separated string of regular expressions.
74      */

75     public static final String JavaDoc PATTERNS_PROPERTY = "plugin.contentFilter.patterns";
76
77     /**
78      * The expected value is a boolean, if true the value of #MASK_PROPERTY will
79      * be used to mask matching content.
80      */

81     public static final String JavaDoc MASK_ENABLED_PROPERTY = "plugin.contentFilter.mask.enabled";
82
83     /**
84      * The expected value is a string. If this property is set any
85      * matching content will not be rejected but masked with the given value.
86      * Setting a content mask means that property #SENDER_NOTIFICATION_ENABLED_PROPERTY
87      * is ignored. The default value is "**".
88      */

89     public static final String JavaDoc MASK_PROPERTY = "plugin.contentFilter.mask";
90
91     /**
92      * the hook into the inteceptor chain
93      */

94     private InterceptorManager interceptorManager;
95
96     /**
97      * used to send violation notifications
98      */

99     private MessageRouter messageRouter;
100
101     /**
102      * delegate that does the real work of this plugin
103      */

104     private ContentFilter contentFilter;
105
106     /**
107      * flags if sender should be notified of rejections
108      */

109     private boolean rejectionNotificationEnabled;
110
111     /**
112      * the rejection msg to send
113      */

114     private String JavaDoc rejectionMessage;
115
116     /**
117      * flags if content matches should result in admin notification
118      */

119     private boolean violationNotificationEnabled;
120
121     /**
122      * the admin user to send violation notifications to
123      */

124     private String JavaDoc violationContact;
125
126     /**
127      * flag if patterns should be used
128      */

129     private boolean patternsEnabled;
130
131     /**
132      * the patterns to use
133      */

134     private String JavaDoc patterns;
135
136     /**
137      * flag if mask should be used
138      */

139     private boolean maskEnabled;
140
141     /**
142      * the mask to use
143      */

144     private String JavaDoc mask;
145
146     /**
147      * violation notification messages will be from this JID
148      */

149     private JID violationNotificationFrom;
150
151     public ContentFilterPlugin() {
152         contentFilter = new ContentFilter();
153         interceptorManager = InterceptorManager.getInstance();
154         violationNotificationFrom = new JID(XMPPServer.getInstance()
155                 .getServerInfo().getName());
156         messageRouter = XMPPServer.getInstance().getMessageRouter();
157     }
158
159     public boolean isMaskEnabled() {
160         return maskEnabled;
161     }
162
163     public void setMaskEnabled(boolean enabled) {
164         maskEnabled = enabled;
165         JiveGlobals.setProperty(MASK_ENABLED_PROPERTY, enabled ? "true" : "false");
166
167         changeContentFilterMask();
168     }
169
170     public void setMask(String JavaDoc mas) {
171         mask = mas;
172         JiveGlobals.setProperty(MASK_PROPERTY, mas);
173
174         changeContentFilterMask();
175     }
176
177     private void changeContentFilterMask() {
178         if (maskEnabled) {
179             contentFilter.setMask(mask);
180         }
181         else {
182             contentFilter.clearMask();
183         }
184     }
185
186     public String JavaDoc getMask() {
187         return mask;
188     }
189
190     public boolean isPatternsEnabled() {
191         return patternsEnabled;
192     }
193
194     public void setPatternsEnabled(boolean enabled) {
195         patternsEnabled = enabled;
196         JiveGlobals.setProperty(PATTERNS_ENABLED_PROPERTY, enabled ? "true"
197                 : "false");
198
199         changeContentFilterPatterns();
200     }
201
202     public void setPatterns(String JavaDoc patt) {
203         patterns = patt;
204         JiveGlobals.setProperty(PATTERNS_PROPERTY, patt);
205
206         changeContentFilterPatterns();
207     }
208
209     private void changeContentFilterPatterns() {
210         if (patternsEnabled) {
211             contentFilter.setPatterns(patterns);
212         }
213         else {
214             contentFilter.clearPatterns();
215         }
216     }
217
218     public String JavaDoc getPatterns() {
219         return patterns;
220     }
221
222     public boolean isRejectionNotificationEnabled() {
223         return rejectionNotificationEnabled;
224     }
225
226     public void setRejectionNotificationEnabled(boolean enabled) {
227         rejectionNotificationEnabled = enabled;
228         JiveGlobals.setProperty(REJECTION_NOTIFICATION_ENABLED_PROPERTY,
229                 enabled ? "true" : "false");
230     }
231
232     public String JavaDoc getRejectionMessage() {
233         return rejectionMessage;
234     }
235
236     public void setRejectionMessage(String JavaDoc message) {
237         this.rejectionMessage = message;
238         JiveGlobals.setProperty(REJECTION_MSG_PROPERTY, message);
239     }
240
241     public boolean isViolationNotificationEnabled() {
242         return violationNotificationEnabled;
243     }
244
245     public void setViolationNotificationEnabled(boolean enabled) {
246         violationNotificationEnabled = enabled;
247         JiveGlobals.setProperty(VIOLATION_NOTIFICATION_ENABLED_PROPERTY,
248                 enabled ? "true" : "false");
249     }
250
251     public void setViolationContact(String JavaDoc contact) {
252         violationContact = contact;
253         JiveGlobals.setProperty(VIOLATION_NOTIFICATION_CONTACT_PROPERTY, contact);
254     }
255
256     public String JavaDoc getViolationContact() {
257         return violationContact;
258     }
259
260     public void initializePlugin(PluginManager pManager, File JavaDoc pluginDirectory) {
261         // configure this plugin
262
initFilter();
263
264         // register with interceptor manager
265
interceptorManager.addInterceptor(this);
266     }
267
268     private void initFilter() {
269         // default to false
270
violationNotificationEnabled = JiveGlobals.getBooleanProperty(
271                 VIOLATION_NOTIFICATION_ENABLED_PROPERTY, false);
272
273         // default to "admin"
274
violationContact = JiveGlobals.getProperty(VIOLATION_NOTIFICATION_CONTACT_PROPERTY,
275                 "admin");
276
277         // default to false
278
rejectionNotificationEnabled = JiveGlobals.getBooleanProperty(
279                 REJECTION_NOTIFICATION_ENABLED_PROPERTY, false);
280
281         // default to english
282
rejectionMessage = JiveGlobals.getProperty(REJECTION_MSG_PROPERTY,
283                 "Message rejected. This is an automated server response");
284
285         // default to false
286
patternsEnabled = JiveGlobals.getBooleanProperty(PATTERNS_ENABLED_PROPERTY,
287                 false);
288
289         //default to "fox,dog"
290
patterns = JiveGlobals.getProperty(PATTERNS_PROPERTY, "fox,dog");
291
292         changeContentFilterPatterns();
293
294         // default to false
295
maskEnabled = JiveGlobals.getBooleanProperty(MASK_ENABLED_PROPERTY, false);
296
297         //default to "***"
298
mask = JiveGlobals.getProperty(MASK_PROPERTY, "***");
299
300         changeContentFilterMask();
301     }
302
303     /**
304      * @see org.jivesoftware.messenger.container.Plugin#destroyPlugin()
305      */

306     public void destroyPlugin() {
307         // unregister with interceptor manager
308
interceptorManager.removeInterceptor(this);
309     }
310
311
312     public void interceptPacket(Packet packet, Session session, boolean read,
313             boolean processed) throws PacketRejectedException {
314         if (patternsEnabled && !processed && (packet instanceof Message)) {
315             Message msg = (Message) packet;
316
317             // filter the message
318
boolean contentMatched = contentFilter.filter(msg);
319
320             // notify contact of violations
321
if (contentMatched && violationNotificationEnabled) {
322                 sendViolationNotification(msg);
323             }
324
325             // reject the message if not masking content
326
if (contentMatched && !maskEnabled) {
327                 PacketRejectedException rejected = new PacketRejectedException(
328                         "Message rejected with disallowed content!");
329
330                 if (rejectionNotificationEnabled) {
331                     // let the sender know about the rejection, this is
332
// only possible/useful if the content is not masked
333
rejected.setRejectionMessage(rejectionMessage);
334                 }
335
336                 throw rejected;
337             }
338         }
339     }
340
341     private void sendViolationNotification(Message offendingMsg) {
342         String JavaDoc subject = "Content filter notification!";
343
344         String JavaDoc msg = "Disallowed content detected in message from:"
345                 + offendingMsg.getFrom() + " to:" + offendingMsg.getTo()
346                 + ", message was "
347                 + (contentFilter.isMaskingContent() ? "altered" : "rejected");
348
349         messageRouter.route(createServerMessage(subject, msg));
350     }
351
352     private Message createServerMessage(String JavaDoc subject, String JavaDoc body) {
353         Message message = new Message();
354         message.setTo(violationContact + "@"
355                 + violationNotificationFrom.getDomain());
356         message.setFrom(violationNotificationFrom);
357         message.setSubject(subject);
358         message.setBody(body);
359         return message;
360     }
361 }
Popular Tags