Something about deleting roster item

hi all,

If a & b are friends. a delete b from its roster items, and then a is removed from b’s roster items.

I saw most IMs doesn’t look like this. when a user delete a friend, it won’t affect the others

Can you modify this situation?

Hello,

You could certainly modify Openfire or possibly create a plugin that would enable this behavior but it would not conform to the XMPP/RFC3921 spec; see section 7.6.

Cheers,

Ryan

Thanks,

But I would rather write a plugin because modifing openfire will lead our maintance hard

/**
 * Remove the roster item from the sender's roster (and possibly the recipient's).
 * Actual roster removal is done in the removeItem(Roster,RosterItem) method.
 *
 * @param roster The sender's roster.
 * @param sender The JID of the sender of the removal request
 * @param item   The removal item element
 */
private void removeItem(org.jivesoftware.openfire.roster.Roster roster, JID sender,
        org.xmpp.packet.Roster.Item item) throws SharedGroupException {
    JID recipient = item.getJID();
    // Remove recipient from the sender's roster
    roster.deleteRosterItem(item.getJID(), true);
    // Forward set packet to the subscriber
    if (localServer.isLocal(recipient)) { // Recipient is local so let's handle it here
        try {
            Roster recipientRoster = userManager.getUser(recipient.getNode()).getRoster();
            recipientRoster.deleteRosterItem(sender, true);
        }
        catch (UserNotFoundException e) {
            // Do nothing
        }
    }
    else {
        // Recipient is remote so we just forward the packet to them
        String serverDomain = localServer.getServerInfo().getXMPPDomain();
        // Check if the recipient may be hosted by this server
        if (!recipient.getDomain().contains(serverDomain)) {
            // TODO Implete when s2s is implemented
        }
        else {
            Packet removePacket = createRemoveForward(sender, recipient);
            router.route(removePacket);
        }
    }
}

Here’s the code of deleting a friend. But I’m not sure how to change this situation by plugin? Anyoen helps me?

Hi Ryan,

I don’t think that Openfire and or Spark handle the rosters right. One can read in the document `Upon receiving the presence stanza of type “unsubscribed”, the user SHOULD acknowledge receipt of that subscription state notification through either “affirming” it by sending a presence stanza of type “unsubscribe” to the contact or “denying” it by sending a presence stanza of type “subscribe” to the contact´.

One should - from my point of view - also be able to add a user to the roster without sending a subscription request. This seems to be described in “7.4. Adding a Roster Item”.

LG

Hi LG,

Hmm… good questions. I’m not sure if Openfire is incorrect I’d have to study it a bit more. But, looking at the smack documentation the add/deleting of roster entries automatically triggers the sending of subscription packets which is probably the typical use case but could cause unintended consequences in some situations.

-Ryan

Hi Naku,

if you want to write a plugin you should be familar with the Spark debug window which allows to send simple XMPP packets. It seems that one needs to debug first what’s going on - maybe this is a client problem. Can you look into this?

If this is an Openfire problem one needs to fix it, then a plugin will likely not be needed.

LG

If openfire would change this situation, it would be very glad.

But if not, is there any approach that a plugin can change this situation?

I had pasted the code.

You can see that in that method

1 roster.deleteRosterItem(item.getJID(), true);

2 recipientRoster.deleteRosterItem(sender, true);

If I simply removed the 2rd line, it will be like what I want.

But I really want to change it by writing a new plugin instead of modifying the code of openfire

I am having the same problem and I believe Openfire behaves wrong.

Any chance, someone will fix it soon? Otherwise, how could implement a plugin, that corrects the behavior?

http://xmpp.org/rfcs/rfc3921.html#int-remove

Note: When the user removes the contact from the user’s roster, the end state of the contact’s roster is that the user is still in the contact’s roster with a subscription state of “none”; in order to completely remove the roster item for the user, the contact needs to also send a roster removal request.

I developed a plugin that does the job. Basically it overrides the default behavior by adding a IQHandler to the router. MyIQRosterHandler is just a copy of Openfire’s IQRosterHandler, where removeItem only has a single line of code:

roster.deleteRosterItem(item.getJID(), true);

``

public class DeleteRosterItemPlugin implements Plugin {     private IQHandler myHandler = new MyIQRosterHandler();     public void initializePlugin(PluginManager manager, File pluginDirectory) {         myHandler = new MyIQRosterHandler();
        IQRouter iqRouter = XMPPServer.getInstance().getIQRouter();
        iqRouter.addHandler(myHandler);
    }     public void destroyPlugin() {
        IQRouter iqRouter = XMPPServer.getInstance().getIQRouter();
        iqRouter.removeHandler(myHandler);
        myHandler = null;
    }
}

It works for me, although I suspected that adding an IQHandler is just that, adding behavior, and not overriding it. But I debugged, and the original IQRosterHandler wasn’t called anymore.

Tested with Openfire 3.7.0.

Hello

I am using openfire 3.6.4 & I want to write a webservice to delete the user from all user’s roster when it gets deleted from openldap, for this I checked the any utility/plugin on internet then I found userservice plugin to delete user but this plugiun can not delete user from ldap says it is readonly (I checked dcoumentation), so I decided to write a plugin which has a servlet in it where I want to call code to delete contact from rosters, the plugin is successfully installed after openfire restart but call to the servlet from url returns empty page, though it has some text to print also the log statements are not appered in log.

The directory structure of the plugin is

plugins

|

|---- webserviceplugin

|

|---- classes (contains servlet class in sub folders)

|---- plugin.xml

|---- web

|

|---- WEB-INF

|

|---- web-custom.xml (contains servlet mapping for newly written servlet)

|---- web.xml

The url I am using to call the webservice is

http://192.168.0.40:9090/plugins/webserviceplugin/webservice

Hi,

can someone file a bug for this issue in Jira? It is still present in Openfire 3.8.2.

Current wrong behavior (as described above):

User A and B have subscription state “both” and are on both rosters. A deletes B. Wrong consequence: A is also deleted on B’s roster.

It should be:

B is only deleted on A’s roster.

A’s server sends “unsubscribe” and “unsubscribed” to B.

See: http://xmpp.org/rfcs/rfc6121.html#roster-delete-success

*As with adding a roster item, if the server can successfully process the roster set then it MUST update the item in the user’s roster, send a roster push to all of the user’s interested resources (with the ‘subscription’ attribute set to a value of “remove”), and send an IQ result to the initiating resource; details are provided under Section 2.3. *

*In addition, the user’s server might need to generate one or more subscription-related presence stanzas, as follows: *

  1. *If the user has a presence subscription to the contact, then the user’s server MUST send a presence stanza of type “unsubscribe” to the contact (in order to unsubscribe from the contact’s presence). *
  2. *If the contact has a presence subscription to the user, then the user’s server MUST send a presence stanza of type “unsubscribed” to the contact (in order to cancel the contact’s subscription to the user). *
  3. *I**f the presence subscription is mutual, then the user’s server MUST send both a presence stanza of type “unsubscribe” and a presence stanza of type “unsubscribed” to the contact. ***