PubSub Affiliation Modifications

BTW (not directly related) I was playing around with node.modifyAffiliationAsOwner() on ejabberd (16.03):

  • created a node as admin
  • set affiliation to user foo as member

And so managed to ‘lock’ myself out - I could not delete the node anymore as admin. The server reporting I (admin) was not an owner… neither could I delete the node as ‘foo’. To delete it I had to set the affiliation to admin as owner.

According to the PubSub RFC, setting the affiliation should work as ‘delta’ - as I understand it - adding foo should keep admin as owner and just add foo as member.

            An entity may subscribe or retrieve items only if on a whitelist managed by the node owner.
            The node owner MUST automatically be on the whitelist. In order to add entities to the whitelist,
            the node owner SHOULD use the protocol specified in the Manage Affiliated Entities section of this
            document, specifically by setting the affiliation to "member".

Maybe I misinterpreted “The node owner MUST automatically be on the whitelist”… does this mean the client should always add the owner or that it’s the servers job to keep it there?

I tried also node.getAffiliations() (was getting NPE with getAffiliationsAsOwner) and I saw only foo as member…

As said this is just BTW… have to write some testcases to see how this works. I’ll post when I have more data (possibly try ejabberd 18).

For my use case it would be nice if I could control access to a node with a whitelist but it seems like the implementation (at least on ejabberd) is a bit shaky. It would be very impractical if to add a user I had to always update the whole whitelist (what would happen if two admins update the node’s whitelist at the same time).

Nit, but it’s an XEP and not an IETF RFC.

That is also how I read XEP-0060 § 8.9.2.1

I think this means that the server has to treat the owner always as admin.

I think chances are good that ejabberd 18 shows better behavior here. Let us know the results of your experiments.

@Flow so I installed ejabberd 18.01 and retested.

Affiliations now work as expected - i.e. I don’t get locked out - adding someone as member will not remove the owner.

I have a few questions on the API, though.

  1. Using node.getAffiliations() will return just the calling user affiliations on the node, right?
    Let’s say userA creates nodeA. If userA calls node.getAffiliations() it will get 1 affiliation as owner. If userB calls node.getAffiliations() it will get no affiliations.
    If then userA adds userB as member… If userA calls node.getAffiliations() it will (again) get 1 affiliation as owner. If userB calls node.getAffiliations() it will get 1 affiliation as member.

  2. As the owner of the node I’d like to see all users affiliated to the node. Is this what node.getAffiliationsAsOwner() does?
    I tried calling node.getAffiliationsAsOwner() but I get a NPE. In the log I see that the server responded with the correct list (i.e. in the example above userA/owner, userB/member), though.

<iq xml:lang='en' to='userA@xxx.net/222221037151381953778' from='pubsub.xxx.net' type='result' id='LYGJd-67'><pubsub xmlns='http://jabber.org/protocol/pubsub#owner'><affiliations node='nodeA'><affiliation affiliation='member' jid='userB@xxx.net'/><affiliation affiliation='owner' jid='userA@xxx.net'/></affiliations></pubsub></iq>

The stacktrace is (Smack 4.2.3):

java.lang.NullPointerException
	at org.jivesoftware.smackx.pubsub.Node.getAffiliations(Node.java:318)
	at org.jivesoftware.smackx.pubsub.Node.getAffiliationsAsOwner(Node.java:300)
	at org.jivesoftware.smackx.pubsub.Node.getAffiliationsAsOwner(Node.java:277)

Problem happens here:

        AffiliationsExtension affilElem = reply.getExtension(PubSubElementType.AFFILIATIONS);
        return affilElem.getAffiliations();

affilElem is null and then it crashes.

To reproduce: I create a PubSub node, like this:

        ConfigureForm form = new ConfigureForm( DataForm.Type.submit );
        form.setAccessModel( AccessModel.whitelist );
        form.setDeliverPayloads( false );
        form.setNotifyRetract( true );
        form.setPersistentItems( true );
        form.setMaxItems( 100 );
        form.setTitle( nodeTitle );
        form.setPublishModel( PublishModel.open );

… and then just call node.getAffiliationsAsOwner().

I believe so, yes. See also XEP-0060 § 5.7

That is likely a bug in Smack. I’ve created SMACK-814. Note that the fix will only go into Smack 4.3 and not into 4.2.

@Flow Thanks. Do you have a date for 4.3?

No, but snapshot releases are always available.