MultiUserChat#changeSubject times out without auth

I think that there’s a bug in org.jivesoftware.smackx.muc.MultiUserChat#changeSubject - it is documented to throw XMPPException.XMPPErrorException if someone without appropriate privileges attempts to change the room subject will throw an error with code 403 (i.e. Forbidden). It instead seems to give a no-response.

I asserted that the server does send a <forbidden>, as shown below.

This was executed against version 4.5.0-alpha4-SNAPSHOT

@SmackIntegrationTest(section = "8.1", quote =
    "modify the subject [...] MUST be denied if the <user@host> of the 'from' address of the request does not match " +
    "the bare JID portion of one of the moderators; in this case, the service MUST return a <forbidden/> error.")
public void mucTestVisitorNotAllowedToChangeSubject() throws Exception
{
    final EntityBareJid mucAddress = getRandomRoom("smack-inttest-visitor-change-subject");
    final MultiUserChat mucAsSeenByOne = mucManagerOne.getMultiUserChat(mucAddress);
    final MultiUserChat mucAsSeenByTwo = mucManagerTwo.getMultiUserChat(mucAddress);

    final Resourcepart nicknameOne = Resourcepart.from("one-" + randomString);
    final Resourcepart nicknameTwo = Resourcepart.from("two-" + randomString);

    createMuc(mucAsSeenByOne, nicknameOne);
    try {
        final FormField field = mucAsSeenByOne.getConfigurationForm().getField("muc#roomconfig_changesubject");
        if (field != null && ((BooleanFormField) field).getValueAsBoolean()) {
            throw new TestNotPossibleException("Room is configured to allow subject changes from participants.");
        }
        mucAsSeenByTwo.join(nicknameTwo);

        final XMPPException.XMPPErrorException e = assertThrows(XMPPException.XMPPErrorException.class, () -> {
            mucAsSeenByTwo.changeSubject("Test Subject Change " +  StringUtils.insecureRandomString(6));
        }, "Expected an error after '" + conTwo.getUser() + "' (that is not a moderator) tried to change the subject of room '" + mucAddress + "' (but none occurred).");
        assertEquals(StanzaError.Condition.forbidden, e.getStanzaError().getCondition(), "Unexpected error condition in the (expected) error that was returned to '" + conTwo.getUser() + "' after it tried to change to subject of room '" + mucAddress + "' while not being a moderator.");
    } finally {
        tryDestroy(mucAsSeenByOne);
    }
}

XMPP data log:

15:54:39.522 SENT (2): 
<message to='smack-inttest-visitor-change-subject-8zrav-8cvkus@conference.example.org' id='GQHWG-15' type='groupchat'>
  <subject>
    Test Subject Change 22E6WM
  </subject>
</message>
<r xmlns='urn:xmpp:sm:3'/>
15:54:39.523 RECV (2): 
<message to="smack-inttest-two-8zrav@example.org/two-8zrav" id="GQHWG-15" type="error" from="smack-inttest-visitor-change-subject-8zrav-8cvkus@conference.example.org">
  <subject>
    Test Subject Change 22E6WM
  </subject>
  <stanza-id xmlns="urn:xmpp:sid:0" id="ad3a1387-d464-4471-8bec-e666af56fd64" by="smack-inttest-visitor-change-subject-8zrav-8cvkus@conference.example.org"/>
  <error code="403" type="auth">
    <forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <text xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
      You are not allowed to change the subject of this room.
    </text>
  </error>
</message>

Test failure log:

SEVERE: MultiUserChatModeratorIntegrationTest.mucTestVisitorNotAllowedToChangeSubject (Normal) failed: org.opentest4j.AssertionFailedError: Expected an error after 'smack-inttest-two-8zrav@example.org/two-8zrav' (that is not a moderator) tried to change the subject of room 'smack-inttest-visitor-change-subject-8zrav-8cvkus@conference.example.org' (but none occurred). ==> Unexpected exception type thrown ==> expected: <org.jivesoftware.smack.XMPPException.XMPPErrorException> but was: <org.jivesoftware.smack.SmackException.NoResponseException>
org.opentest4j.AssertionFailedError: Expected an error after 'smack-inttest-two-8zrav@example.org/two-8zrav' (that is not a moderator) tried to change the subject of room 'smack-inttest-visitor-change-subject-8zrav-8cvkus@conference.example.org' (but none occurred). ==> Unexpected exception type thrown ==> expected: <org.jivesoftware.smack.XMPPException.XMPPErrorException> but was: <org.jivesoftware.smack.SmackException.NoResponseException>
	at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:65)
	at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:41)
	at org.junit.jupiter.api.Assertions.assertThrows(Assertions.java:2936)
	at org.jivesoftware.smackx.muc.MultiUserChatModeratorIntegrationTest.mucTestVisitorNotAllowedToChangeSubject(MultiUserChatModeratorIntegrationTest.java:122)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.lambda$runTests$0(SmackIntegrationTestFramework.java:476)
	at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.runConcreteTest(SmackIntegrationTestFramework.java:551)
	at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework$PreparedTest.run(SmackIntegrationTestFramework.java:759)
	at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.runTests(SmackIntegrationTestFramework.java:539)
	at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.run(SmackIntegrationTestFramework.java:277)
	at org.igniterealtime.smack.inttest.SmackIntegrationTestFramework.main(SmackIntegrationTestFramework.java:115)
Caused by: org.jivesoftware.smack.SmackException$NoResponseException: No response received within reply timeout. Timeout was 5000ms (~5s). StanzaCollector has been cancelled. Waited for response using: AndFilter: (AndFilter: (FromMatchesFilter (ignoreResourcepart): smack-inttest-visitor-change-subject-8zrav-8cvkus@conference.example.org, MessageTypeFilter: type=groupchat), org.jivesoftware.smackx.muc.MultiUserChat$5@1107c465).
	at org.jivesoftware.smack.SmackException$NoResponseException.newWith(SmackException.java:124)
	at org.jivesoftware.smack.SmackException$NoResponseException.newWith(SmackException.java:104)
	at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:281)
	at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:228)
	at org.jivesoftware.smackx.muc.MultiUserChat.changeSubject(MultiUserChat.java:2263)
	at org.jivesoftware.smackx.muc.MultiUserChatModeratorIntegrationTest.lambda$mucTestVisitorNotAllowedToChangeSubject$1(MultiUserChatModeratorIntegrationTest.java:123)
	at org.junit.jupiter.api.AssertThrows.assertThrows(AssertThrows.java:55)
	... 13 more

Proposed fix: [muc] changeSubject errors should be propagated by guusdk · Pull Request #596 · igniterealtime/Smack · GitHub