use of org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent in project Openfire by igniterealtime.
the class LocalMUCRoom method joinRoom.
@Override
public LocalMUCRole joinRoom(String nickname, String password, HistoryRequest historyRequest, LocalMUCUser user, Presence presence) throws UnauthorizedException, UserAlreadyExistsException, RoomLockedException, ForbiddenException, RegistrationRequiredException, ConflictException, ServiceUnavailableException, NotAcceptableException {
if (((MultiUserChatServiceImpl) mucService).getMUCDelegate() != null) {
if (!((MultiUserChatServiceImpl) mucService).getMUCDelegate().joiningRoom(this, user.getAddress())) {
// Delegate said no, reject join.
throw new UnauthorizedException();
}
}
LocalMUCRole joinRole = null;
lock.writeLock().lock();
boolean clientOnlyJoin = false;
// A "client only join" here is one where the client is already joined, but has re-joined.
try {
// If the room has a limit of max user then check if the limit has been reached
if (!canJoinRoom(user)) {
throw new ServiceUnavailableException();
}
final JID bareJID = user.getAddress().asBareJID();
boolean isOwner = owners.includes(bareJID);
// If the room is locked and this user is not an owner raise a RoomLocked exception
if (isLocked()) {
if (!isOwner) {
throw new RoomLockedException();
}
}
// Check if the nickname is already used in the room
if (occupantsByNickname.containsKey(nickname.toLowerCase())) {
List<MUCRole> occupants = occupantsByNickname.get(nickname.toLowerCase());
MUCRole occupant = occupants.size() > 0 ? occupants.get(0) : null;
if (occupant != null && !occupant.getUserAddress().toBareJID().equals(bareJID.toBareJID())) {
// Nickname is already used, and not by the same JID
throw new UserAlreadyExistsException();
}
if (occupant.getUserAddress().equals(user.getAddress())) {
// This user is already an occupant. The client thinks it isn't. (Or else this is a broken gmail).
clientOnlyJoin = true;
}
}
// Unauthorized exception
if (isPasswordProtected()) {
if (password == null || !password.equals(getPassword())) {
throw new UnauthorizedException();
}
}
// raise a ConflictException
if (members.containsValue(nickname.toLowerCase())) {
if (!nickname.toLowerCase().equals(members.get(bareJID))) {
throw new ConflictException();
}
}
if (isLoginRestrictedToNickname()) {
String reservedNickname = members.get(bareJID);
if (reservedNickname != null && !nickname.toLowerCase().equals(reservedNickname)) {
throw new NotAcceptableException();
}
}
// Set the corresponding role based on the user's affiliation
MUCRole.Role role;
MUCRole.Affiliation affiliation;
if (isOwner) {
// The user is an owner. Set the role and affiliation accordingly.
role = MUCRole.Role.moderator;
affiliation = MUCRole.Affiliation.owner;
} else if (mucService.isSysadmin(bareJID)) {
// The user is a system administrator of the MUC service. Treat him as an owner
// although he won't appear in the list of owners
role = MUCRole.Role.moderator;
affiliation = MUCRole.Affiliation.owner;
} else if (admins.includes(bareJID)) {
// The user is an admin. Set the role and affiliation accordingly.
role = MUCRole.Role.moderator;
affiliation = MUCRole.Affiliation.admin;
} else // explicit outcast status has higher precedence than member status
if (outcasts.contains(bareJID)) {
// The user is an outcast. Raise a "Forbidden" exception.
throw new ForbiddenException();
} else if (members.includesKey(bareJID)) {
// The user is a member. Set the role and affiliation accordingly.
role = MUCRole.Role.participant;
affiliation = MUCRole.Affiliation.member;
} else // this checks if the user is an outcast implicitly (via a group)
if (outcasts.includes(bareJID)) {
// The user is an outcast. Raise a "Forbidden" exception.
throw new ForbiddenException();
} else {
// The user has no affiliation (i.e. NONE). Set the role accordingly.
if (isMembersOnly()) {
// "Registration Required" exception.
throw new RegistrationRequiredException();
}
role = (isModerated() ? MUCRole.Role.visitor : MUCRole.Role.participant);
affiliation = MUCRole.Affiliation.none;
}
if (!clientOnlyJoin) {
// Create a new role for this user in this room
joinRole = new LocalMUCRole(mucService, this, nickname, role, affiliation, user, presence, router);
// Add the new user as an occupant of this room
List<MUCRole> occupants = occupantsByNickname.get(nickname.toLowerCase());
if (occupants == null) {
occupants = new ArrayList<>();
occupantsByNickname.put(nickname.toLowerCase(), occupants);
}
occupants.add(joinRole);
// Update the tables of occupants based on the bare and full JID
List<MUCRole> list = occupantsByBareJID.get(bareJID);
if (list == null) {
list = new ArrayList<>();
occupantsByBareJID.put(bareJID, list);
}
list.add(joinRole);
occupantsByFullJID.put(user.getAddress(), joinRole);
} else {
// Grab the existing one.
joinRole = (LocalMUCRole) occupantsByFullJID.get(user.getAddress());
}
} finally {
lock.writeLock().unlock();
}
// Notify other cluster nodes that a new occupant joined the room
CacheFactory.doClusterTask(new OccupantAddedEvent(this, joinRole));
// Send presence of existing occupants to new occupant
sendInitialPresences(joinRole);
// It is assumed that the room is new based on the fact that it's locked and
// that it was locked when it was created.
boolean isRoomNew = isLocked() && creationDate.getTime() == lockedTime;
try {
// Send the presence of this new occupant to existing occupants
Presence joinPresence = joinRole.getPresence().createCopy();
broadcastPresence(joinPresence, true);
} catch (Exception e) {
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
// confirmed" message
if (!isRoomNew && isLocked()) {
// http://xmpp.org/extensions/xep-0045.html#enter-locked
Presence presenceItemNotFound = new Presence(Presence.Type.error);
presenceItemNotFound.setError(PacketError.Condition.item_not_found);
presenceItemNotFound.setFrom(role.getRoleAddress());
joinRole.send(presenceItemNotFound);
}
if (historyRequest == null) {
Iterator<Message> history = roomHistory.getMessageHistory();
while (history.hasNext()) {
joinRole.send(history.next());
}
} else {
historyRequest.sendHistory(joinRole, roomHistory);
}
Message roomSubject = roomHistory.getChangedSubject();
if (roomSubject != null) {
joinRole.send(roomSubject);
}
if (!clientOnlyJoin) {
// Update the date when the last occupant left the room
setEmptyDate(null);
// Fire event that occupant joined the room
MUCEventDispatcher.occupantJoined(getRole().getRoleAddress(), user.getAddress(), joinRole.getNickname());
}
return joinRole;
}
use of org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent in project Openfire by igniterealtime.
the class MultiUserChatManager method joinedCluster.
// Cluster management tasks
@Override
public void joinedCluster() {
if (!ClusterManager.isSeniorClusterMember()) {
// Get transient rooms and persistent rooms with occupants from senior
// cluster member and merge with local ones. If room configuration was
// changed in both places then latest configuration will be kept
@SuppressWarnings("unchecked") List<ServiceInfo> result = (List<ServiceInfo>) CacheFactory.doSynchronousClusterTask(new SeniorMemberServicesRequest(), ClusterManager.getSeniorClusterMember().toByteArray());
if (result != null) {
for (ServiceInfo serviceInfo : result) {
MultiUserChatService service;
service = XMPPServer.getInstance().getMultiUserChatManager().getMultiUserChatService(serviceInfo.getSubdomain());
if (service == null) {
// This is a service we don't know about yet, create it locally and register it;
service = new MultiUserChatServiceImpl(serviceInfo.getSubdomain(), serviceInfo.getDescription(), serviceInfo.isHidden());
XMPPServer.getInstance().getMultiUserChatManager().registerMultiUserChatService(service);
}
MultiUserChatServiceImpl serviceImpl = (MultiUserChatServiceImpl) service;
for (RoomInfo roomInfo : serviceInfo.getRooms()) {
LocalMUCRoom remoteRoom = roomInfo.getRoom();
LocalMUCRoom localRoom = serviceImpl.getLocalChatRoom(remoteRoom.getName());
if (localRoom == null) {
// Create local room with remote information
localRoom = remoteRoom;
serviceImpl.chatRoomAdded(localRoom);
} else {
// Update local room with remote information
localRoom.updateConfiguration(remoteRoom);
}
// TODO Handle conflict of nicknames
for (OccupantAddedEvent event : roomInfo.getOccupants()) {
event.setSendPresence(true);
event.run();
}
}
}
}
}
}
use of org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent in project Openfire by igniterealtime.
the class MultiUserChatManager method joinedCluster.
@Override
@SuppressWarnings("unchecked")
public void joinedCluster(byte[] nodeID) {
Object result = CacheFactory.doSynchronousClusterTask(new GetNewMemberRoomsRequest(), nodeID);
if (result instanceof List<?>) {
List<RoomInfo> rooms = (List<RoomInfo>) result;
for (RoomInfo roomInfo : rooms) {
LocalMUCRoom remoteRoom = roomInfo.getRoom();
MultiUserChatServiceImpl service = (MultiUserChatServiceImpl) remoteRoom.getMUCService();
LocalMUCRoom localRoom = service.getLocalChatRoom(remoteRoom.getName());
if (localRoom == null) {
// Create local room with remote information
localRoom = remoteRoom;
service.chatRoomAdded(localRoom);
}
// Add remote occupants to local room
for (OccupantAddedEvent event : roomInfo.getOccupants()) {
event.setSendPresence(true);
event.run();
}
}
}
}
use of org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent in project Openfire by igniterealtime.
the class MultiUserChatServiceImpl method getChatRoom.
@Override
public MUCRoom getChatRoom(String roomName, JID userjid) throws NotAllowedException {
LocalMUCRoom room;
boolean loaded = false;
boolean created = false;
synchronized (roomName.intern()) {
room = localMUCRoomManager.getRoom(roomName);
if (room == null) {
room = new LocalMUCRoom(this, roomName, router);
// If the room is persistent load the configuration values from the DB
try {
// Try to load the room's configuration from the database (if the room is
// persistent but was added to the DB after the server was started up or the
// room may be an old room that was not present in memory)
MUCPersistenceManager.loadFromDB(room);
loaded = true;
} catch (IllegalArgumentException e) {
// (or was deleted somehow and is expected to exist by a delegate).
if (mucEventDelegate != null && mucEventDelegate.shouldRecreate(roomName, userjid)) {
if (mucEventDelegate.loadConfig(room)) {
loaded = true;
if (room.isPersistent()) {
MUCPersistenceManager.saveToDB(room);
}
} else {
// not allow room creation
throw new NotAllowedException();
}
} else {
// The room does not exist so check for creation permissions
// Room creation is always allowed for sysadmin
final JID bareJID = userjid.asBareJID();
if (isRoomCreationRestricted() && !sysadmins.includes(bareJID)) {
// The room creation is only allowed for certain JIDs
if (!allowedToCreate.includes(bareJID)) {
// an exception
throw new NotAllowedException();
}
}
room.addFirstOwner(userjid);
created = true;
}
}
localMUCRoomManager.addRoom(roomName, room);
}
}
if (created) {
// Fire event that a new room has been created
MUCEventDispatcher.roomCreated(room.getRole().getRoleAddress());
}
if (loaded || created) {
// Notify other cluster nodes that a new room is available
CacheFactory.doClusterTask(new RoomAvailableEvent(room));
for (MUCRole role : room.getOccupants()) {
if (role instanceof LocalMUCRole) {
CacheFactory.doClusterTask(new OccupantAddedEvent(room, role));
}
}
}
return room;
}
Aggregations