in server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCIqAdminHandler.java [201:311]
private Stanza changeAffiliation(IQStanza stanza, ServerRuntimeContext serverRuntimeContext,
SessionContext sessionContext, IqAdminItem item, Room room, Occupant moderator, StanzaBroker stanzaBroker) {
// only allowed by admins and owners
if (moderator.getAffiliation() != Affiliation.Admin && moderator.getAffiliation() != Affiliation.Owner) {
return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL, StanzaErrorCondition.NOT_ALLOWED);
}
Entity target = null;
if (item.getNick() != null) {
target = room.findOccupantByNick(item.getNick()).getJid();
} else {
try {
if (item.getJid() != null) {
target = item.getJid();
} else {
return createBadRequestError(stanza, serverRuntimeContext, sessionContext, "Missing nick for item");
}
} catch (EntityFormatException e) {
return createBadRequestError(stanza, serverRuntimeContext, sessionContext, "Invalid JID");
}
}
Affiliation currentAffiliation = room.getAffiliations().getAffiliation(target);
Affiliation newAffiliation = item.getAffiliation();
// if the target is present in the room, we need to send presence updates
// otherwise we should send messages
Occupant targetOccupant = room.findOccupantByJID(target);
// notify remaining users that user got affiliation updated
PresenceStanzaType presenceType = null;
Status status = null;
Role newRole;
Entity from;
if (targetOccupant != null) {
newRole = targetOccupant.getRole();
from = roomAndNick(room, targetOccupant);
} else {
newRole = Role.None;
from = room.getJID();
}
// only owners can revoke ownership and admin
if ((currentAffiliation == Affiliation.Owner || currentAffiliation == Affiliation.Admin)
&& moderator.getAffiliation() != Affiliation.Owner) {
return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL, StanzaErrorCondition.NOT_ALLOWED);
}
// if the occupant is getting revoke as a member, and this is a members-only
// room, he also needs to leave the room
if ((newAffiliation == Affiliation.None && room.isRoomType(RoomType.MembersOnly))
|| newAffiliation == Affiliation.Outcast) {
if (newAffiliation == Affiliation.Outcast && currentAffiliation.compareTo(moderator.getAffiliation()) < 0) {
return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
StanzaErrorCondition.NOT_ALLOWED);
}
if (targetOccupant != null) {
room.removeOccupant(target);
}
presenceType = PresenceStanzaType.UNAVAILABLE;
if (newAffiliation == Affiliation.Outcast) {
status = new Status(StatusCode.BEEN_BANNED);
} else {
status = new Status(StatusCode.REMOVED_BY_AFFILIATION);
}
newRole = Role.None;
MucUserItem presenceItem = new MucUserItem(newAffiliation, newRole);
if (targetOccupant != null) {
Stanza presenceToFormerMember = MUCStanzaBuilder.createPresenceStanza(from, target, presenceType,
NamespaceURIs.XEP0045_MUC_USER, presenceItem, status);
relayStanza(target, presenceToFormerMember, stanzaBroker);
}
} else if (newAffiliation == Affiliation.Owner || newAffiliation == Affiliation.Admin) {
if (moderator.getAffiliation() != Affiliation.Owner) {
return MUCHandlerHelper.createErrorReply(stanza, StanzaErrorType.CANCEL,
StanzaErrorCondition.NOT_ALLOWED);
}
}
room.getAffiliations().add(target, newAffiliation);
if (targetOccupant != null) {
MucUserItem presenceItem = new MucUserItem(newAffiliation, newRole);
for (Occupant occupant : room.getOccupants()) {
Stanza presenceToRemaining = MUCStanzaBuilder.createPresenceStanza(from, occupant.getJid(),
presenceType, NamespaceURIs.XEP0045_MUC_USER, presenceItem, status);
relayStanza(occupant.getJid(), presenceToRemaining, stanzaBroker);
}
} else {
room.getAffiliations().add(target, newAffiliation);
MucUserItem presenceItem = new MucUserItem(target, null, newAffiliation, Role.None);
for (Occupant occupant : room.getOccupants()) {
StanzaBuilder builder = StanzaBuilder.createMessageStanza(room.getJID(), occupant.getJid(), null, null);
builder.addPreparedElement(presenceItem);
relayStanza(occupant.getJid(), builder.build(), stanzaBroker);
}
}
return StanzaBuilder.createIQStanza(stanza.getTo(), stanza.getFrom(), IQStanzaType.RESULT, stanza.getID())
.build();
}