Search in sources :

Example 1 with OccupantAddedEvent

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;
}
Also used : ForbiddenException(org.jivesoftware.openfire.muc.ForbiddenException) GroupJID(org.jivesoftware.openfire.group.GroupJID) JID(org.xmpp.packet.JID) Message(org.xmpp.packet.Message) ConflictException(org.jivesoftware.openfire.muc.ConflictException) OccupantAddedEvent(org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent) ServiceUnavailableException(org.jivesoftware.openfire.muc.ServiceUnavailableException) UserAlreadyExistsException(org.jivesoftware.openfire.user.UserAlreadyExistsException) ForbiddenException(org.jivesoftware.openfire.muc.ForbiddenException) GroupNotFoundException(org.jivesoftware.openfire.group.GroupNotFoundException) RoomLockedException(org.jivesoftware.openfire.muc.RoomLockedException) CannotBeInvitedException(org.jivesoftware.openfire.muc.CannotBeInvitedException) NotAllowedException(org.jivesoftware.openfire.muc.NotAllowedException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) NotFoundException(org.jivesoftware.util.NotFoundException) ConflictException(org.jivesoftware.openfire.muc.ConflictException) RegistrationRequiredException(org.jivesoftware.openfire.muc.RegistrationRequiredException) UserAlreadyExistsException(org.jivesoftware.openfire.user.UserAlreadyExistsException) IOException(java.io.IOException) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) NotAcceptableException(org.jivesoftware.openfire.muc.NotAcceptableException) ServiceUnavailableException(org.jivesoftware.openfire.muc.ServiceUnavailableException) MUCRole(org.jivesoftware.openfire.muc.MUCRole) NotAcceptableException(org.jivesoftware.openfire.muc.NotAcceptableException) RoomLockedException(org.jivesoftware.openfire.muc.RoomLockedException) UnauthorizedException(org.jivesoftware.openfire.auth.UnauthorizedException) Presence(org.xmpp.packet.Presence) UpdatePresence(org.jivesoftware.openfire.muc.cluster.UpdatePresence) RegistrationRequiredException(org.jivesoftware.openfire.muc.RegistrationRequiredException)

Example 2 with OccupantAddedEvent

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();
                    }
                }
            }
        }
    }
}
Also used : ServiceInfo(org.jivesoftware.openfire.muc.cluster.ServiceInfo) SeniorMemberServicesRequest(org.jivesoftware.openfire.muc.cluster.SeniorMemberServicesRequest) LocalMUCRoom(org.jivesoftware.openfire.muc.spi.LocalMUCRoom) MultiUserChatServiceImpl(org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl) RoomInfo(org.jivesoftware.openfire.muc.cluster.RoomInfo) ArrayList(java.util.ArrayList) List(java.util.List) OccupantAddedEvent(org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent)

Example 3 with OccupantAddedEvent

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();
            }
        }
    }
}
Also used : LocalMUCRoom(org.jivesoftware.openfire.muc.spi.LocalMUCRoom) MultiUserChatServiceImpl(org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl) RoomInfo(org.jivesoftware.openfire.muc.cluster.RoomInfo) ArrayList(java.util.ArrayList) List(java.util.List) OccupantAddedEvent(org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent) GetNewMemberRoomsRequest(org.jivesoftware.openfire.muc.cluster.GetNewMemberRoomsRequest)

Example 4 with OccupantAddedEvent

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;
}
Also used : MUCRole(org.jivesoftware.openfire.muc.MUCRole) NotAllowedException(org.jivesoftware.openfire.muc.NotAllowedException) GroupJID(org.jivesoftware.openfire.group.GroupJID) RoomAvailableEvent(org.jivesoftware.openfire.muc.cluster.RoomAvailableEvent) OccupantAddedEvent(org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent)

Aggregations

OccupantAddedEvent (org.jivesoftware.openfire.muc.cluster.OccupantAddedEvent)4 ArrayList (java.util.ArrayList)2 List (java.util.List)2 GroupJID (org.jivesoftware.openfire.group.GroupJID)2 MUCRole (org.jivesoftware.openfire.muc.MUCRole)2 NotAllowedException (org.jivesoftware.openfire.muc.NotAllowedException)2 RoomInfo (org.jivesoftware.openfire.muc.cluster.RoomInfo)2 LocalMUCRoom (org.jivesoftware.openfire.muc.spi.LocalMUCRoom)2 MultiUserChatServiceImpl (org.jivesoftware.openfire.muc.spi.MultiUserChatServiceImpl)2 IOException (java.io.IOException)1 UnauthorizedException (org.jivesoftware.openfire.auth.UnauthorizedException)1 GroupNotFoundException (org.jivesoftware.openfire.group.GroupNotFoundException)1 CannotBeInvitedException (org.jivesoftware.openfire.muc.CannotBeInvitedException)1 ConflictException (org.jivesoftware.openfire.muc.ConflictException)1 ForbiddenException (org.jivesoftware.openfire.muc.ForbiddenException)1 NotAcceptableException (org.jivesoftware.openfire.muc.NotAcceptableException)1 RegistrationRequiredException (org.jivesoftware.openfire.muc.RegistrationRequiredException)1 RoomLockedException (org.jivesoftware.openfire.muc.RoomLockedException)1 ServiceUnavailableException (org.jivesoftware.openfire.muc.ServiceUnavailableException)1 GetNewMemberRoomsRequest (org.jivesoftware.openfire.muc.cluster.GetNewMemberRoomsRequest)1