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();
}