Disabling instant messaging

I’‘m doing this for work. We want to use Wildfire as our server so that we can have chatroom capabilites. But we don’'t want the employees to be able to privately instant message each other. I was told by my co-worker, that in order to disable instant messaging I would have to create a plugin for it. Is that the only way?

I am completely new to writing plugins. I was looking through the source code trying to find something I could do to disable private instant messaging. I couldn’'t find anything. I also looked through the Wildfire API and no luck there either.

How is private instant messaging treated by Wildfire? Is it treated as a chatroom with only two people?

I’'m thinking I could block all messages going from user to user.

Hi Jigar,

Your co-work is correct, out-of-the-box Wildfire does not provide a way to disable person-to-person/private messaging; however, writing a plugin to disable such messaging is pretty straight forward.

If you look at XEP-0045 (which defines how multi-user chat works) you’‘ll notice that all groupchat messages must, in part send a message of type “groupchat”. So, what we want to do with our plugin is create a PacketInterceptor that will inspect each message packet, check the packet’'s type and if its not of type “groupchat” reject it. Easy enough, right? Below is the code that will do that all for us:

import java.io.File; import org.jivesoftware.wildfire.Session;
import org.jivesoftware.wildfire.container.Plugin;
import org.jivesoftware.wildfire.container.PluginManager;
import org.jivesoftware.wildfire.interceptor.InterceptorManager;
import org.jivesoftware.wildfire.interceptor.PacketInterceptor;
import org.jivesoftware.wildfire.interceptor.PacketRejectedException;
import org.xmpp.packet.Message;
import org.xmpp.packet.Packet; public class PrivateMessageDisablerPlugin implements Plugin {
    private MessagePacketInterceptor interceptor = new MessagePacketInterceptor();     public void initializePlugin(PluginManager manager, File pluginDirectory) {
       //register our interceptor when the plugin is loaded
       InterceptorManager.getInstance().addInterceptor(interceptor);
    }     public void destroyPlugin() {
       //remove our interceptor so the plugin can be unloaded cleanly
       InterceptorManager.getInstance().removeInterceptor(interceptor);
    }
        private class MessagePacketInterceptor implements PacketInterceptor {
       public void interceptPacket(Packet packet, Session session, boolean incoming, boolean processed) throws PacketRejectedException {
           //check each packet to see if its a message
           if ((packet instanceof Message) && !processed) {
              Message message = (Message) packet;               //if we find a message that isn''t of type groupchat reject it
              if (message.getType() != Message.Type.groupchat) {
                 throw new PacketRejectedException();
              }
           }
       }
    }
}

I haven’‘t extensively tested this plugin but I think it will pretty much do what you’'re looking for. Other than some more testing the only thing left for you to do is to take a look at the Plugin Developer Guide to see how to package up this code into a plugin. If you get stuck let me know.

Hope that helps,

Ryan

Hey Ryan!

Didn’'t expect you to do all the work. What I was thinking is actually what you just did. I spent the last 3-4 hours going through the Wildfire source code and trying to find out which function actually sends the message out to the client. I looked some more through the API also and figured out that Message extends Packet and that Message has a Message.Type property.

These are the files I thought were sending out the messages to the client:

org.jivesoftware.wildfire.spi.PacketDelivererImpl.java

org.jivesoftware.wildfire.MessageRouter.java

What I did in PacketDelivererImpl.java was:

public void deliver(Packet packet) throws UnauthorizedException, PacketException {
  if (packet == null) {
    throw new PacketException("Packet was null");
  }
  if (deliverHandler == null) {
    throw new PacketException("Could not send packet - no route" + packet.toString());
  }   // Start of my code --------   Message msg = (Message) packet;   if (msg.getType() == Message.Type.chat) {
    msg.setTo(packet.getFrom());  // This redirects the message back.
    msg.setFrom("System");  // This sets the From to System.
    msg.setBody("Private Instant Messaging is diabled");  // Changes the body of the message
    packet = (Packet) msg;  // Cast it as a packet and overwrite the existing packet object.
  }   //  End of my code ------   deliverHandler.process(packet);
}

Unfortunately it did not work. I tired the samething MessageRouter.java and the same result. Oh well, I’'ll just go ahead and write a plugin for now, but I definetely want to find out which class/function sends out the packets/messages.

BTW, how do I make my code appear like your’'s in an IFrame and Courier New font?

Thanks Ryan

Hi Jigar,

Typically, altering the Wildfire source isn’‘t the best way to implement the kind of change you’‘re wanting to make. Making changes to the core source can lead to unexpected side-effects and can become a pain to manage if you ever want to upgrade to a newer version of Wildfire. Having said that, there’'s a couple of places where you could alter the Wildfire source to do the same thing the plugin does. Probably the best thing to do would be to either alter SocketReader#processMessage or write your own implementation of the ClientSocketReader class and override the processMessage method.

As for formatting code that you post to the forums, wrap you code in … tags, without the spaces.

Hope that helps,

Ryan

Thanks a lot for your help Ryan. I’'m surprized I got help so fast. This project has very good developer support. Hope this project gets more attention and grows bigger.