private Stanza changeRole()

in server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java [313:397]


    private Stanza changeRole(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext,
            IqAdminItem item, Room room, Occupant moderator, StanzaBroker stanzaBroker) {
        Occupant target = null;
        if (item.getNick() != null) {
            target = room.findOccupantByNick(item.getNick());
        } else {
            return createBadRequestError(stanza, serverRuntimeContext, sessionContext, "Missing nick for item");
        }

        Role newRole = item.getRole();
        // you can not change yourself
        if (moderator.getJid().equals(target.getJid())) {
            return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL, StanzaErrorCondition.CONFLICT);
        }

        // verify change
        if (newRole == Role.None) {
            // a moderator can not kick someone with a higher affiliation
            if (target.getAffiliation().compareTo(moderator.getAffiliation()) < 0) {
                return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
                        StanzaErrorCondition.NOT_ALLOWED);
            }
        } else if (newRole == Role.Visitor) {
            // moderator, admin and owner can not have their voice revoked
            if (target.getAffiliation() == Affiliation.Admin || target.getAffiliation() == Affiliation.Owner) {
                return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
                        StanzaErrorCondition.NOT_ALLOWED);
            }
        } else if (newRole == Role.Participant) {
            if (target.getRole() == Role.Moderator) {
                // only admin and owner might revoke moderator
                if (moderator.getAffiliation() != Affiliation.Admin
                        && moderator.getAffiliation() != Affiliation.Owner) {
                    return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
                            StanzaErrorCondition.NOT_ALLOWED);
                }
                // admin and owners can not be revoked
                if (target.getAffiliation() == Affiliation.Admin || target.getAffiliation() == Affiliation.Owner) {
                    return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
                            StanzaErrorCondition.NOT_ALLOWED);
                }
            }
        } else if (newRole == Role.Moderator) {
            // only admin and owner might grant moderator
            if (moderator.getAffiliation() != Affiliation.Admin && moderator.getAffiliation() != Affiliation.Owner) {
                return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
                        StanzaErrorCondition.NOT_ALLOWED);
            }
        }
        target.setRole(newRole);
        if (newRole == Role.None) {
            // remove user from room
            room.removeOccupant(target.getJid());
        }

        Entity targetInRoom = roomAndNick(room, target);

        Status status = null;
        if (newRole == Role.None) {
            status = new Status(StatusCode.BEEN_KICKED);

            // notify user he got kicked
            Stanza presenceToKicked = MUCStanzaBuilder.createPresenceStanza(targetInRoom, target.getJid(),
                    PresenceStanzaType.UNAVAILABLE, NamespaceURIs.XEP0045_MUC_USER,
                    new MucUserItem(Affiliation.None, Role.None),
                    // TODO handle <actor>
                    // TODO handle <reason>
                    status);

            relayStanza(target.getJid(), presenceToKicked, stanzaBroker);
        }

        PresenceStanzaType availType = (newRole == Role.None) ? PresenceStanzaType.UNAVAILABLE : null;

        // notify remaining users that user got role updated
        MucUserItem presenceItem = new MucUserItem(target.getAffiliation(), newRole);
        for (Occupant occupant : room.getOccupants()) {
            Stanza presenceToRemaining = MUCStanzaBuilder.createPresenceStanza(targetInRoom, occupant.getJid(),
                    availType, NamespaceURIs.XEP0045_MUC_USER, presenceItem, status);

            relayStanza(occupant.getJid(), presenceToRemaining, stanzaBroker);
        }
        return StanzaBuilder.createIQStanza(stanza.getTo(), stanza.getFrom(), IQStanzaType.RESULT, stanza.getID())
                .build();
    }