Commit ef99bfef authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Fixed deadlock that could freeze entire JVM. JM-1372

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10438 b35dd754-fafc-0310-a699-88a17e54d16e
parent 4587f830
...@@ -216,49 +216,43 @@ public class IQAdminHandler { ...@@ -216,49 +216,43 @@ public class IQAdminHandler {
jid = room.getOccupant(nick).getUserAddress(); jid = room.getOccupant(nick).getUserAddress();
} }
room.lock.writeLock().lock(); if ("moderator".equals(target)) {
try { // Add the user as a moderator of the room based on the full JID
if ("moderator".equals(target)) { presences.add(room.addModerator(jid, senderRole));
// Add the user as a moderator of the room based on the full JID } else if ("participant".equals(target)) {
presences.add(room.addModerator(jid, senderRole)); // Add the user as a participant of the room based on the full JID
} else if ("participant".equals(target)) { presences.add(room.addParticipant(jid,
// Add the user as a participant of the room based on the full JID item.elementTextTrim("reason"),
presences.add(room.addParticipant(jid, senderRole));
item.elementTextTrim("reason"), } else if ("visitor".equals(target)) {
senderRole)); // Add the user as a visitor of the room based on the full JID
} else if ("visitor".equals(target)) { presences.add(room.addVisitor(jid, senderRole));
// Add the user as a visitor of the room based on the full JID } else if ("member".equals(target)) {
presences.add(room.addVisitor(jid, senderRole)); // Add the user as a member of the room based on the bare JID
} else if ("member".equals(target)) { boolean hadAffiliation = room.getAffiliation(jid.toBareJID()) != MUCRole.Affiliation.none;
// Add the user as a member of the room based on the bare JID presences.addAll(room.addMember(jid.toBareJID(), nick, senderRole));
boolean hadAffiliation = room.getAffiliation(jid.toBareJID()) != MUCRole.Affiliation.none; // If the user had an affiliation don't send an invitation. Otherwise
presences.addAll(room.addMember(jid.toBareJID(), nick, senderRole)); // send an invitation if the room is members-only
// If the user had an affiliation don't send an invitation. Otherwise if (!hadAffiliation && room.isMembersOnly()) {
// send an invitation if the room is members-only room.sendInvitation(jid, null, senderRole, null);
if (!hadAffiliation && room.isMembersOnly()) { }
room.sendInvitation(jid, null, senderRole, null); } else if ("outcast".equals(target)) {
} // Add the user as an outcast of the room based on the bare JID
} else if ("outcast".equals(target)) { presences.addAll(room.addOutcast(jid.toBareJID(), item.elementTextTrim("reason"), senderRole));
// Add the user as an outcast of the room based on the bare JID } else if ("none".equals(target)) {
presences.addAll(room.addOutcast(jid.toBareJID(), item.elementTextTrim("reason"), senderRole)); if (hasAffiliation) {
} else if ("none".equals(target)) { // Set that this jid has a NONE affiliation based on the bare JID
if (hasAffiliation) { presences.addAll(room.addNone(jid.toBareJID(), senderRole));
// Set that this jid has a NONE affiliation based on the bare JID
presences.addAll(room.addNone(jid.toBareJID(), senderRole));
} else {
// Kick the user from the room
if (MUCRole.Role.moderator != senderRole.getRole()) {
throw new ForbiddenException();
}
presences.add(room.kickOccupant(jid, senderRole.getUserAddress(),
item.elementTextTrim("reason")));
}
} else { } else {
reply.setError(PacketError.Condition.bad_request); // Kick the user from the room
if (MUCRole.Role.moderator != senderRole.getRole()) {
throw new ForbiddenException();
}
presences.add(room.kickOccupant(jid, senderRole.getUserAddress(),
item.elementTextTrim("reason")));
} }
} } else {
finally { reply.setError(PacketError.Condition.bad_request);
room.lock.writeLock().unlock();
} }
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
......
...@@ -20,10 +20,10 @@ import org.jivesoftware.openfire.forms.DataForm; ...@@ -20,10 +20,10 @@ import org.jivesoftware.openfire.forms.DataForm;
import org.jivesoftware.openfire.forms.FormField; import org.jivesoftware.openfire.forms.FormField;
import org.jivesoftware.openfire.forms.spi.XDataFormImpl; import org.jivesoftware.openfire.forms.spi.XDataFormImpl;
import org.jivesoftware.openfire.forms.spi.XFormFieldImpl; import org.jivesoftware.openfire.forms.spi.XFormFieldImpl;
import org.jivesoftware.openfire.muc.CannotBeInvitedException;
import org.jivesoftware.openfire.muc.ConflictException; import org.jivesoftware.openfire.muc.ConflictException;
import org.jivesoftware.openfire.muc.ForbiddenException; import org.jivesoftware.openfire.muc.ForbiddenException;
import org.jivesoftware.openfire.muc.MUCRole; import org.jivesoftware.openfire.muc.MUCRole;
import org.jivesoftware.openfire.muc.CannotBeInvitedException;
import org.jivesoftware.openfire.muc.cluster.RoomUpdatedEvent; import org.jivesoftware.openfire.muc.cluster.RoomUpdatedEvent;
import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.LocaleUtils; import org.jivesoftware.util.LocaleUtils;
...@@ -240,7 +240,6 @@ public class IQOwnerHandler { ...@@ -240,7 +240,6 @@ public class IQOwnerHandler {
} }
room.lock.readLock().unlock(); room.lock.readLock().unlock();
room.lock.writeLock().lock();
try { try {
for (String bareJID : jids.keySet()) { for (String bareJID : jids.keySet()) {
String targetAffiliation = jids.get(bareJID); String targetAffiliation = jids.get(bareJID);
...@@ -266,7 +265,6 @@ public class IQOwnerHandler { ...@@ -266,7 +265,6 @@ public class IQOwnerHandler {
} }
} }
finally { finally {
room.lock.writeLock().unlock();
room.lock.readLock().lock(); room.lock.readLock().lock();
} }
} }
...@@ -369,180 +367,173 @@ public class IQOwnerHandler { ...@@ -369,180 +367,173 @@ public class IQOwnerHandler {
// Keep a registry of the updated presences // Keep a registry of the updated presences
List<Presence> presences = new ArrayList<Presence>(admins.size() + owners.size()); List<Presence> presences = new ArrayList<Presence>(admins.size() + owners.size());
room.lock.writeLock().lock(); field = completedForm.getField("muc#roomconfig_roomname");
try { if (field != null) {
field = completedForm.getField("muc#roomconfig_roomname"); values = field.getValues();
if (field != null) { room.setNaturalLanguageName((values.hasNext() ? values.next() : " "));
values = field.getValues(); }
room.setNaturalLanguageName((values.hasNext() ? values.next() : " "));
}
field = completedForm.getField("muc#roomconfig_roomdesc"); field = completedForm.getField("muc#roomconfig_roomdesc");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
room.setDescription((values.hasNext() ? values.next() : " ")); room.setDescription((values.hasNext() ? values.next() : " "));
} }
field = completedForm.getField("muc#roomconfig_changesubject"); field = completedForm.getField("muc#roomconfig_changesubject");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setCanOccupantsChangeSubject(("1".equals(booleanValue))); room.setCanOccupantsChangeSubject(("1".equals(booleanValue)));
} }
field = completedForm.getField("muc#roomconfig_maxusers"); field = completedForm.getField("muc#roomconfig_maxusers");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
room.setMaxUsers((values.hasNext() ? Integer.parseInt(values.next()) : 30)); room.setMaxUsers((values.hasNext() ? Integer.parseInt(values.next()) : 30));
} }
field = completedForm.getField("muc#roomconfig_presencebroadcast"); field = completedForm.getField("muc#roomconfig_presencebroadcast");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
list = new ArrayList<String>(); list = new ArrayList<String>();
while (values.hasNext()) { while (values.hasNext()) {
list.add(values.next()); list.add(values.next());
}
room.setRolesToBroadcastPresence(list);
} }
room.setRolesToBroadcastPresence(list);
}
field = completedForm.getField("muc#roomconfig_publicroom"); field = completedForm.getField("muc#roomconfig_publicroom");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setPublicRoom(("1".equals(booleanValue))); room.setPublicRoom(("1".equals(booleanValue)));
} }
field = completedForm.getField("muc#roomconfig_persistentroom"); field = completedForm.getField("muc#roomconfig_persistentroom");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
boolean isPersistent = ("1".equals(booleanValue)); boolean isPersistent = ("1".equals(booleanValue));
// Delete the room from the DB if it's no longer persistent // Delete the room from the DB if it's no longer persistent
if (room.isPersistent() && !isPersistent) { if (room.isPersistent() && !isPersistent) {
MUCPersistenceManager.deleteFromDB(room); MUCPersistenceManager.deleteFromDB(room);
}
room.setPersistent(isPersistent);
} }
room.setPersistent(isPersistent);
}
field = completedForm.getField("muc#roomconfig_moderatedroom"); field = completedForm.getField("muc#roomconfig_moderatedroom");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setModerated(("1".equals(booleanValue))); room.setModerated(("1".equals(booleanValue)));
} }
field = completedForm.getField("muc#roomconfig_membersonly"); field = completedForm.getField("muc#roomconfig_membersonly");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
presences.addAll(room.setMembersOnly(("1".equals(booleanValue)))); presences.addAll(room.setMembersOnly(("1".equals(booleanValue))));
} }
field = completedForm.getField("muc#roomconfig_allowinvites"); field = completedForm.getField("muc#roomconfig_allowinvites");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setCanOccupantsInvite(("1".equals(booleanValue))); room.setCanOccupantsInvite(("1".equals(booleanValue)));
} }
field = completedForm.getField("muc#roomconfig_passwordprotectedroom"); field = completedForm.getField("muc#roomconfig_passwordprotectedroom");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
boolean isPasswordProtected = "1".equals(booleanValue); boolean isPasswordProtected = "1".equals(booleanValue);
if (isPasswordProtected) { if (isPasswordProtected) {
// The room is password protected so set the new password // The room is password protected so set the new password
field = completedForm.getField("muc#roomconfig_roomsecret"); field = completedForm.getField("muc#roomconfig_roomsecret");
if (field != null) { if (field != null) {
values = completedForm.getField("muc#roomconfig_roomsecret").getValues(); values = completedForm.getField("muc#roomconfig_roomsecret").getValues();
room.setPassword((values.hasNext() ? values.next() : null)); room.setPassword((values.hasNext() ? values.next() : null));
}
}
else {
// The room is not password protected so remove any previous password
room.setPassword(null);
} }
} }
else {
field = completedForm.getField("muc#roomconfig_whois"); // The room is not password protected so remove any previous password
if (field != null) { room.setPassword(null);
values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setCanAnyoneDiscoverJID(("anyone".equals(booleanValue)));
} }
}
field = completedForm.getField("muc#roomconfig_enablelogging"); field = completedForm.getField("muc#roomconfig_whois");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setLogEnabled(("1".equals(booleanValue))); room.setCanAnyoneDiscoverJID(("anyone".equals(booleanValue)));
} }
field = completedForm.getField("x-muc#roomconfig_reservednick"); field = completedForm.getField("muc#roomconfig_enablelogging");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setLoginRestrictedToNickname(("1".equals(booleanValue))); room.setLogEnabled(("1".equals(booleanValue)));
} }
field = completedForm.getField("x-muc#roomconfig_canchangenick"); field = completedForm.getField("x-muc#roomconfig_reservednick");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setChangeNickname(("1".equals(booleanValue))); room.setLoginRestrictedToNickname(("1".equals(booleanValue)));
} }
field = completedForm.getField("x-muc#roomconfig_registration"); field = completedForm.getField("x-muc#roomconfig_canchangenick");
if (field != null) { if (field != null) {
values = field.getValues(); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1"); booleanValue = (values.hasNext() ? values.next() : "1");
room.setRegistrationEnabled(("1".equals(booleanValue))); room.setChangeNickname(("1".equals(booleanValue)));
} }
// Update the modification date to reflect the last time when the room's configuration field = completedForm.getField("x-muc#roomconfig_registration");
// was modified if (field != null) {
room.setModificationDate(new Date()); values = field.getValues();
booleanValue = (values.hasNext() ? values.next() : "1");
room.setRegistrationEnabled(("1".equals(booleanValue)));
}
if (room.isPersistent()) { // Update the modification date to reflect the last time when the room's configuration
room.saveToDB(); // was modified
} room.setModificationDate(new Date());
// Set the new owners and admins of the room if (room.isPersistent()) {
presences.addAll(room.addOwners(owners, senderRole)); room.saveToDB();
presences.addAll(room.addAdmins(admins, senderRole)); }
if (ownersSent) {
// Change the affiliation to "member" for the current owners that won't be neither
// owner nor admin (if the form included the owners field)
List<String> ownersToRemove = new ArrayList<String>(room.owners);
ownersToRemove.removeAll(admins);
ownersToRemove.removeAll(owners);
for (String jid : ownersToRemove) {
presences.addAll(room.addMember(jid, null, senderRole));
}
}
if (adminsSent) { // Set the new owners and admins of the room
// Change the affiliation to "member" for the current admins that won't be neither presences.addAll(room.addOwners(owners, senderRole));
// owner nor admin (if the form included the admins field) presences.addAll(room.addAdmins(admins, senderRole));
List<String> adminsToRemove = new ArrayList<String>(room.admins);
adminsToRemove.removeAll(admins);
adminsToRemove.removeAll(owners);
for (String jid : adminsToRemove) {
presences.addAll(room.addMember(jid, null, senderRole));
}
}
// Destroy the room if the room is no longer persistent and there are no occupants in if (ownersSent) {
// the room // Change the affiliation to "member" for the current owners that won't be neither
if (!room.isPersistent() && room.getOccupantsCount() == 0) { // owner nor admin (if the form included the owners field)
room.destroyRoom(null, null); List<String> ownersToRemove = new ArrayList<String>(room.owners);
ownersToRemove.removeAll(admins);
ownersToRemove.removeAll(owners);
for (String jid : ownersToRemove) {
presences.addAll(room.addMember(jid, null, senderRole));
} }
}
if (adminsSent) {
// Change the affiliation to "member" for the current admins that won't be neither
// owner nor admin (if the form included the admins field)
List<String> adminsToRemove = new ArrayList<String>(room.admins);
adminsToRemove.removeAll(admins);
adminsToRemove.removeAll(owners);
for (String jid : adminsToRemove) {
presences.addAll(room.addMember(jid, null, senderRole));
}
} }
finally {
room.lock.writeLock().unlock(); // Destroy the room if the room is no longer persistent and there are no occupants in
// the room
if (!room.isPersistent() && room.getOccupantsCount() == 0) {
room.destroyRoom(null, null);
} }
// Send the updated presences to the room occupants // Send the updated presences to the room occupants
......
...@@ -1233,33 +1233,39 @@ public class LocalMUCRoom implements MUCRoom { ...@@ -1233,33 +1233,39 @@ public class LocalMUCRoom implements MUCRoom {
} }
public List<Presence> addOwner(String bareJID, MUCRole sendRole) throws ForbiddenException { public List<Presence> addOwner(String bareJID, MUCRole sendRole) throws ForbiddenException {
MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none; lock.writeLock().lock();
if (MUCRole.Affiliation.owner != sendRole.getAffiliation()) { try {
throw new ForbiddenException(); MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none;
if (MUCRole.Affiliation.owner != sendRole.getAffiliation()) {
throw new ForbiddenException();
}
// Check if user is already an owner
if (owners.contains(bareJID)) {
// Do nothing
return Collections.emptyList();
}
owners.add(bareJID);
// Remove the user from other affiliation lists
if (removeAdmin(bareJID)) {
oldAffiliation = MUCRole.Affiliation.admin;
}
else if (removeMember(bareJID)) {
oldAffiliation = MUCRole.Affiliation.member;
}
else if (removeOutcast(bareJID)) {
oldAffiliation = MUCRole.Affiliation.outcast;
}
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
null,
MUCRole.Affiliation.owner,
oldAffiliation);
} }
// Check if user is already an owner finally {
if (owners.contains(bareJID)) { lock.writeLock().unlock();
// Do nothing
return Collections.emptyList();
} }
owners.add(bareJID);
// Remove the user from other affiliation lists
if (removeAdmin(bareJID)) {
oldAffiliation = MUCRole.Affiliation.admin;
}
else if (removeMember(bareJID)) {
oldAffiliation = MUCRole.Affiliation.member;
}
else if (removeOutcast(bareJID)) {
oldAffiliation = MUCRole.Affiliation.outcast;
}
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
null,
MUCRole.Affiliation.owner,
oldAffiliation);
// Update the presence with the new affiliation and inform all occupants // Update the presence with the new affiliation and inform all occupants
try { try {
return changeOccupantAffiliation(bareJID, MUCRole.Affiliation.owner, return changeOccupantAffiliation(bareJID, MUCRole.Affiliation.owner,
...@@ -1277,37 +1283,43 @@ public class LocalMUCRoom implements MUCRoom { ...@@ -1277,37 +1283,43 @@ public class LocalMUCRoom implements MUCRoom {
public List<Presence> addAdmin(String bareJID, MUCRole sendRole) throws ForbiddenException, public List<Presence> addAdmin(String bareJID, MUCRole sendRole) throws ForbiddenException,
ConflictException { ConflictException {
MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none; lock.writeLock().lock();
if (MUCRole.Affiliation.owner != sendRole.getAffiliation()) { try {
throw new ForbiddenException(); MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none;
if (MUCRole.Affiliation.owner != sendRole.getAffiliation()) {
throw new ForbiddenException();
}
// Check that the room always has an owner
if (owners.contains(bareJID) && owners.size() == 1) {
throw new ConflictException();
}
// Check if user is already an admin
if (admins.contains(bareJID)) {
// Do nothing
return Collections.emptyList();
}
admins.add(bareJID);
// Remove the user from other affiliation lists
if (removeOwner(bareJID)) {
oldAffiliation = MUCRole.Affiliation.owner;
}
else if (removeMember(bareJID)) {
oldAffiliation = MUCRole.Affiliation.member;
}
else if (removeOutcast(bareJID)) {
oldAffiliation = MUCRole.Affiliation.outcast;
}
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
null,
MUCRole.Affiliation.admin,
oldAffiliation);
}
finally {
lock.writeLock().unlock();
} }
// Check that the room always has an owner
if (owners.contains(bareJID) && owners.size() == 1) {
throw new ConflictException();
}
// Check if user is already an admin
if (admins.contains(bareJID)) {
// Do nothing
return Collections.emptyList();
}
admins.add(bareJID);
// Remove the user from other affiliation lists
if (removeOwner(bareJID)) {
oldAffiliation = MUCRole.Affiliation.owner;
}
else if (removeMember(bareJID)) {
oldAffiliation = MUCRole.Affiliation.member;
}
else if (removeOutcast(bareJID)) {
oldAffiliation = MUCRole.Affiliation.outcast;
}
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
null,
MUCRole.Affiliation.admin,
oldAffiliation);
// Update the presence with the new affiliation and inform all occupants // Update the presence with the new affiliation and inform all occupants
try { try {
return changeOccupantAffiliation(bareJID, MUCRole.Affiliation.admin, return changeOccupantAffiliation(bareJID, MUCRole.Affiliation.admin,
...@@ -1325,52 +1337,58 @@ public class LocalMUCRoom implements MUCRoom { ...@@ -1325,52 +1337,58 @@ public class LocalMUCRoom implements MUCRoom {
public List<Presence> addMember(String bareJID, String nickname, MUCRole sendRole) public List<Presence> addMember(String bareJID, String nickname, MUCRole sendRole)
throws ForbiddenException, ConflictException { throws ForbiddenException, ConflictException {
MUCRole.Affiliation oldAffiliation = (members.containsKey(bareJID) ? lock.writeLock().lock();
MUCRole.Affiliation.member : MUCRole.Affiliation.none); try {
if (isMembersOnly()) { MUCRole.Affiliation oldAffiliation = (members.containsKey(bareJID) ?
if (!canOccupantsInvite()) { MUCRole.Affiliation.member : MUCRole.Affiliation.none);
if (isMembersOnly()) {
if (!canOccupantsInvite()) {
if (MUCRole.Affiliation.admin != sendRole.getAffiliation()
&& MUCRole.Affiliation.owner != sendRole.getAffiliation()) {
throw new ForbiddenException();
}
}
}
else {
if (MUCRole.Affiliation.admin != sendRole.getAffiliation() if (MUCRole.Affiliation.admin != sendRole.getAffiliation()
&& MUCRole.Affiliation.owner != sendRole.getAffiliation()) { && MUCRole.Affiliation.owner != sendRole.getAffiliation()) {
throw new ForbiddenException(); throw new ForbiddenException();
} }
} }
} // Check if the desired nickname is already reserved for another member
else { if (nickname != null && nickname.trim().length() > 0 && members.containsValue(nickname)) {
if (MUCRole.Affiliation.admin != sendRole.getAffiliation() if (!nickname.equals(members.get(bareJID))) {
&& MUCRole.Affiliation.owner != sendRole.getAffiliation()) { throw new ConflictException();
throw new ForbiddenException(); }
} }
} // Check that the room always has an owner
// Check if the desired nickname is already reserved for another member if (owners.contains(bareJID) && owners.size() == 1) {
if (nickname != null && nickname.trim().length() > 0 && members.containsValue(nickname)) {
if (!nickname.equals(members.get(bareJID))) {
throw new ConflictException(); throw new ConflictException();
} }
// Associate the reserved nickname with the bareJID. If nickname is null then associate an
// empty string
members.put(bareJID, (nickname == null ? "" : nickname));
// Remove the user from other affiliation lists
if (removeOwner(bareJID)) {
oldAffiliation = MUCRole.Affiliation.owner;
}
else if (removeAdmin(bareJID)) {
oldAffiliation = MUCRole.Affiliation.admin;
}
else if (removeOutcast(bareJID)) {
oldAffiliation = MUCRole.Affiliation.outcast;
}
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
nickname,
MUCRole.Affiliation.member,
oldAffiliation);
} }
// Check that the room always has an owner finally {
if (owners.contains(bareJID) && owners.size() == 1) { lock.writeLock().unlock();
throw new ConflictException();
}
// Associate the reserved nickname with the bareJID. If nickname is null then associate an
// empty string
members.put(bareJID, (nickname == null ? "" : nickname));
// Remove the user from other affiliation lists
if (removeOwner(bareJID)) {
oldAffiliation = MUCRole.Affiliation.owner;
}
else if (removeAdmin(bareJID)) {
oldAffiliation = MUCRole.Affiliation.admin;
}
else if (removeOutcast(bareJID)) {
oldAffiliation = MUCRole.Affiliation.outcast;
} }
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
nickname,
MUCRole.Affiliation.member,
oldAffiliation);
// Update other cluster nodes with new member // Update other cluster nodes with new member
CacheFactory.doClusterTask(new AddMember(this, bareJID, (nickname == null ? "" : nickname))); CacheFactory.doClusterTask(new AddMember(this, bareJID, (nickname == null ? "" : nickname)));
// Update the presence with the new affiliation and inform all occupants // Update the presence with the new affiliation and inform all occupants
...@@ -1392,19 +1410,45 @@ public class LocalMUCRoom implements MUCRoom { ...@@ -1392,19 +1410,45 @@ public class LocalMUCRoom implements MUCRoom {
public List<Presence> addOutcast(String bareJID, String reason, MUCRole senderRole) public List<Presence> addOutcast(String bareJID, String reason, MUCRole senderRole)
throws NotAllowedException, ForbiddenException, ConflictException { throws NotAllowedException, ForbiddenException, ConflictException {
MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none; lock.writeLock().lock();
if (MUCRole.Affiliation.admin != senderRole.getAffiliation() try {
&& MUCRole.Affiliation.owner != senderRole.getAffiliation()) { MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none;
throw new ForbiddenException(); if (MUCRole.Affiliation.admin != senderRole.getAffiliation()
} && MUCRole.Affiliation.owner != senderRole.getAffiliation()) {
// Check that the room always has an owner throw new ForbiddenException();
if (owners.contains(bareJID) && owners.size() == 1) { }
throw new ConflictException(); // Check that the room always has an owner
if (owners.contains(bareJID) && owners.size() == 1) {
throw new ConflictException();
}
// Check if user is already an outcast
if (outcasts.contains(bareJID)) {
// Do nothing
return Collections.emptyList();
}
// Update the affiliation lists
outcasts.add(bareJID);
// Remove the user from other affiliation lists
if (removeOwner(bareJID)) {
oldAffiliation = MUCRole.Affiliation.owner;
}
else if (removeAdmin(bareJID)) {
oldAffiliation = MUCRole.Affiliation.admin;
}
else if (removeMember(bareJID)) {
oldAffiliation = MUCRole.Affiliation.member;
}
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
null,
MUCRole.Affiliation.outcast,
oldAffiliation);
} }
// Check if user is already an outcast finally {
if (outcasts.contains(bareJID)) { lock.writeLock().unlock();
// Do nothing
return Collections.emptyList();
} }
// Update the presence with the new affiliation and inform all occupants // Update the presence with the new affiliation and inform all occupants
// actorJID will be null if the room itself (ie. via admin console) made the request // actorJID will be null if the room itself (ie. via admin console) made the request
...@@ -1430,25 +1474,6 @@ public class LocalMUCRoom implements MUCRoom { ...@@ -1430,25 +1474,6 @@ public class LocalMUCRoom implements MUCRoom {
// Effectively kick the occupant from the room // Effectively kick the occupant from the room
kickPresence(presence, actorJID); kickPresence(presence, actorJID);
} }
// Update the affiliation lists
outcasts.add(bareJID);
// Remove the user from other affiliation lists
if (removeOwner(bareJID)) {
oldAffiliation = MUCRole.Affiliation.owner;
}
else if (removeAdmin(bareJID)) {
oldAffiliation = MUCRole.Affiliation.admin;
}
else if (removeMember(bareJID)) {
oldAffiliation = MUCRole.Affiliation.member;
}
// Update the DB if the room is persistent
MUCPersistenceManager.saveAffiliationToDB(
this,
bareJID,
null,
MUCRole.Affiliation.outcast,
oldAffiliation);
return updatedPresences; return updatedPresences;
} }
...@@ -1458,34 +1483,39 @@ public class LocalMUCRoom implements MUCRoom { ...@@ -1458,34 +1483,39 @@ public class LocalMUCRoom implements MUCRoom {
public List<Presence> addNone(String bareJID, MUCRole senderRole) throws ForbiddenException, public List<Presence> addNone(String bareJID, MUCRole senderRole) throws ForbiddenException,
ConflictException { ConflictException {
MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none;
if (MUCRole.Affiliation.admin != senderRole.getAffiliation()
&& MUCRole.Affiliation.owner != senderRole.getAffiliation()) {
throw new ForbiddenException();
}
// Check that the room always has an owner
if (owners.contains(bareJID) && owners.size() == 1) {
throw new ConflictException();
}
List<Presence> updatedPresences = null; List<Presence> updatedPresences = null;
boolean wasMember = members.containsKey(bareJID) || admins.contains(bareJID) || boolean wasMember = false;
owners.contains(bareJID); lock.writeLock().lock();
// Remove the user from ALL the affiliation lists try {
if (removeOwner(bareJID)) { MUCRole.Affiliation oldAffiliation = MUCRole.Affiliation.none;
oldAffiliation = MUCRole.Affiliation.owner; if (MUCRole.Affiliation.admin != senderRole.getAffiliation()
} && MUCRole.Affiliation.owner != senderRole.getAffiliation()) {
else if (removeAdmin(bareJID)) { throw new ForbiddenException();
oldAffiliation = MUCRole.Affiliation.admin; }
} // Check that the room always has an owner
else if (removeMember(bareJID)) { if (owners.contains(bareJID) && owners.size() == 1) {
oldAffiliation = MUCRole.Affiliation.member; throw new ConflictException();
}
wasMember = members.containsKey(bareJID) || admins.contains(bareJID) || owners.contains(bareJID);
// Remove the user from ALL the affiliation lists
if (removeOwner(bareJID)) {
oldAffiliation = MUCRole.Affiliation.owner;
}
else if (removeAdmin(bareJID)) {
oldAffiliation = MUCRole.Affiliation.admin;
}
else if (removeMember(bareJID)) {
oldAffiliation = MUCRole.Affiliation.member;
}
else if (removeOutcast(bareJID)) {
oldAffiliation = MUCRole.Affiliation.outcast;
}
// Remove the affiliation of this user from the DB if the room is persistent
MUCPersistenceManager.removeAffiliationFromDB(this, bareJID, oldAffiliation);
} }
else if (removeOutcast(bareJID)) { finally {
oldAffiliation = MUCRole.Affiliation.outcast; lock.writeLock().unlock();
} }
// Remove the affiliation of this user from the DB if the room is persistent
MUCPersistenceManager.removeAffiliationFromDB(this, bareJID, oldAffiliation);
// Update the presence with the new affiliation and inform all occupants // Update the presence with the new affiliation and inform all occupants
try { try {
MUCRole.Role newRole; MUCRole.Role newRole;
......
...@@ -286,13 +286,7 @@ public class LocalMUCUser implements MUCUser { ...@@ -286,13 +286,7 @@ public class LocalMUCUser implements MUCUser {
// Add the user as a member of the room if the room is // Add the user as a member of the room if the room is
// members only // members only
if (room.isMembersOnly()) { if (room.isMembersOnly()) {
room.lock.writeLock().lock(); room.addMember(info.attributeValue("to"), null, role);
try {
room.addMember(info.attributeValue("to"), null, role);
}
finally {
room.lock.writeLock().unlock();
}
} }
// Send the invitation to the invitee // Send the invitation to the invitee
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment