MUC Admin / Moderator Functions

Has anyone been able to successfully use the moderator functionality in XIFF (i.e. the ability to kick users, grant/revoke voice, ban users, etc.)?

I just tried the first of what was to be several simple tests in which I tried to revoke (or grant) voice to a user in my moderated chat room. Although I can log in as the same user using Spark and successfully grant and revoke voice from a user, when I try doing so using XIFF I get a 400 error and the XML stanza seems to indicate an invalid request. The only thing different is the client … the moderator, the chat room, the user being muted, etc. are all the same in both cases … except it works in Spark and fails in XIFF. Is anything required other than just to call setOccupantVoice() passing the nickname of the target user and a true/false indicating whether to grant or revoke voice?

I don’ t know yet if this is just a problem with granting/revoking voice or if it extends to other admin functions … but I will know soon. I’d sure like to know if at least one other person was able to get this to work … anyone?

This is yet another bug. Although occupantNick is one of only two parameters to the setOccupantVoice() method, it is never used anywhere in the method … seems pretty obvious you should need to know WHO to silence before you silence them. I added the nickname to the muc#user item and things appear to be working ok now. I noticed that there is one other minor difference in the XML stanza sent by XIFF and the one dictated by the spec. The specifications indicates that the from attribute on the IQ should be set to the moderators id, but it is left blank by XIFF. At least for openfire, this doesn’t appear to matter (probably because openfire can determine who its from based on who it just received it from), but there are no guarantees that other XMPP servers won’t rely on this being set correctly … or even OpenFire in a subsequent release … so it should probably also be fixed.

I have to say I get more disappointed by the day in this API. This could NEVER have worked so there is no way anyone even came close to testing it. Just a word of warning to anyone thinking about going down the path I’ve chosen … this is not even close to being ready for prime time. It makes for a nice framework around which to build a working API, but it isn’t usable as-is unless you are building something extremely trivial (which was apparently the only kind of tests that were ever attempted). It’s better than starting from scratch, I guess, but not by a lot since you have to spend a lot of time to understand what the authors were thinking before you can even start to patch the bugs. I’m ranting, but as nearly as I can tell I’m ranting to myself so I guess it doesn’t matter. Sighh!!

I also discovered another related problem. Although the three admin ops I have tested (grant/revoke voice and kick user) seem to be working now, XIFF does not appear to include any code to handle the presence events that occur as a result of a grant or revoke voice. In such cases, a presence message is sent to all occupants of the room. The presence message has no type attribute (i.e. available, unavailable, etc.), only a single item child element that contains the new role for the user (e.g. participant if they were granted voice or visitor if it was revoked). Without getting these events it is impossible to notify the user that they have had their voice revoked (or granted). It appears that at least the unavailable part of the presence event generated when a user is kicked or banned works, but I need to do more testing to see if the additional information such as status code and reason are readily accessible in this presence event. Although its hard to say this is a bug (maybe they didn’t intend to include this functionality in this release?), but it is certainly a significant omission in my opinion and should be added to the to-do list. Whether I will have the time and patience to implement it myself is uncertain.

As I feared, banning users did not work either. It fails with error=403, forbidden even though the same admin can ban the same user using Spark.

After more digging, I found the problem(s). First, the function grant() uses MUCUserExtension when it should be MUCAdminExtension … evidence once again that this method was never tested at all. In addition, the finish_admin function which should be called upon receiving a response from the server is declared private … this method is to be invoked by XMPPConnection so this makes it inaccessible … had to declare it as public in order to be visible.

One other minor thing was that the current ban function did not support passing a reason (or a status for that matter). I added reason to the parameter list so that it would at least mirror the functionality of kickOccupant (in my mind ban is merely a more severe form of kick so it makes sense that they should provide similar capabilities). I made the parameter optional so you don’t have to pass it if you don’t want to.

I still believe the presence handling is not adequate. Ban also results in a presence message being sent to all occupants, but right now it isn’t readily distinguished from a kick or a normal leave room event. It may be possible to handle as a normal leave event and determine whether it is a kick or ban, the reason, etc. by just examining the Presence message, but it seems a better solution to generate a specific BanEvent or KickEvent in the framework code to avoid having to do this processing in each and every client application. I am still digging around to see the best way to fix this.

The ironic thing is that early on I went out of my way to extend the event model without ever modifying the core XIFF code … but now I have made so many changes to fix bugs and the like that it hardly seems worth the effort any more. I will probably offer my source and all the changes it includes to the maintainers of XIFF if they are interested, but in the interim if anyone needs a XIFF that actually works, let me know and I’ll be happy to share it. I would hate to have all this work go to waste.

One more thing. I metioned earlier that the from address is missing on all the admin IQ’s for the room. This doesn’t appear to make any difference for OpenFire so far, but the spec does show that it should be there. Also, in at least one place I found a statement that if the from address in the message did not match exactly the JID of one of the room admins then the request should be refused. It didn’t explicitly say what happens if the from is not there and OpenFire appears to have decided to just use the JID for the connection to determine authorization … but I’m not sure this can be assumed for all XMPP servers or even all future releases of OpenFire … so I still think this should be corrected as well to be ‘safe’ compliance with the spec.

Just my 2 cents worth (ok, maybe its more than 2 cents by now).

I have read through the spec for XMPP Core and per my understanding the from attribute in XML Stanzas sent by the client are optional. The server is required to provide a suitable value (bare JID or fully qualified JID, depending on circumstances) if the from attribute is not provided. So I guess this part of XIFF is working per the specification … sending it wouldn’t have hurt anything, but it isn’t required.