You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by be...@apache.org on 2010/12/26 11:52:54 UTC

svn commit: r1052865 - in /mina/vysper/trunk/server/extensions/xep0045-muc/src: main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/ main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/ test/java/org/apache/vysper/xm...

Author: berndf
Date: Sun Dec 26 10:52:53 2010
New Revision: 1052865

URL: http://svn.apache.org/viewvc?rev=1052865&view=rev
Log:
MUC: rewrite requested nick, when already present

Modified:
    mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
    mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
    mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/EnterRoomTestCase.java
    mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/ExitRoomTestCase.java
    mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java

Modified: mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java?rev=1052865&r1=1052864&r2=1052865&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java (original)
+++ mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/MUCPresenceHandler.java Sun Dec 26 10:52:53 2010
@@ -21,6 +21,7 @@ package org.apache.vysper.xmpp.modules.e
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
 
@@ -173,7 +174,22 @@ public class MUCPresenceHandler extends 
         } else {
             logger.debug("{} has requested to enter room {}", newOccupantJid, roomJid);
 
-            if (room.isInRoom(nick)) {
+            boolean nickConflict = room.isInRoom(nick);
+            boolean nickRewritten = false;
+            int counter = 1; // max conflicts, to avoid DoS attacks
+            String rewrittenNick = null;
+            while (nickConflict && counter < 100 && room.rewritesDuplicateNick()) {
+                rewrittenNick = nick + "_" + counter;
+                nickConflict = room.isInRoom(rewrittenNick);
+                if (nickConflict) {
+                    counter++;
+                } else {
+                    nick = rewrittenNick;
+                    nickRewritten = true;
+                }
+            }
+                
+            if (nickConflict) {
                 // user with this nick is already in room
                 return createPresenceErrorStanza(roomJid, newOccupantJid, stanza.getID(), "cancel", "conflict");
             }
@@ -211,7 +227,7 @@ public class MUCPresenceHandler extends 
 
             // relay presence of the newly added occupant to all existing occupants
             for (Occupant occupant : room.getOccupants()) {
-                sendNewOccupantPresenceToExisting(newOccupant, occupant, room, serverRuntimeContext);
+                sendNewOccupantPresenceToExisting(newOccupant, occupant, room, serverRuntimeContext, nickRewritten);
             }
 
             // send discussion history to user
@@ -234,7 +250,7 @@ public class MUCPresenceHandler extends 
 
             // user must by in room, or we do nothing
             if (exitingOccupant != null) {
-                Set<Occupant> allOccupants = room.getOccupants();
+                Collection<Occupant> allOccupants = room.getOccupants();
 
                 room.removeOccupant(occupantJid);
 
@@ -288,7 +304,7 @@ public class MUCPresenceHandler extends 
     }
 
     private void sendNewOccupantPresenceToExisting(Occupant newOccupant, Occupant existingOccupant, Room room,
-            ServerRuntimeContext serverRuntimeContext) {
+                                                   ServerRuntimeContext serverRuntimeContext, boolean nickRewritten) {
         Entity roomAndNewUserNick = new EntityImpl(room.getJID(), newOccupant.getNick());
 
         List<XMLElement> inner = new ArrayList<XMLElement>();
@@ -307,6 +323,7 @@ public class MUCPresenceHandler extends 
 
             // send status to indicate that this is the users own presence
             inner.add(new Status(StatusCode.OWN_PRESENCE));
+            if (nickRewritten) inner.add(new Status(StatusCode.NICK_MODIFIED));
         }
 
         Stanza presenceToExisting = MUCStanzaBuilder.createPresenceStanza(roomAndNewUserNick,

Modified: mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java?rev=1052865&r1=1052864&r2=1052865&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java (original)
+++ mina/vysper/trunk/server/extensions/xep0045-muc/src/main/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/Room.java Sun Dec 26 10:52:53 2010
@@ -55,6 +55,8 @@ public class Room implements InfoRequest
     private String name;
 
     private String password;
+    
+    private boolean rewriteDuplicateNick = true;
 
     private DiscussionHistory history = new DiscussionHistory();
 
@@ -106,6 +108,14 @@ public class Room implements InfoRequest
         return roomTypes.contains(type);
     }
 
+    public boolean rewritesDuplicateNick() {
+        return rewriteDuplicateNick;
+    }
+
+    public void setRewriteDuplicateNick(boolean rewriteDuplicateNick) {
+        this.rewriteDuplicateNick = rewriteDuplicateNick;
+    }
+
     public Occupant addOccupant(Entity occupantJid, String name) {
         Affiliation affiliation = affiliations.getAffiliation(occupantJid);
 
@@ -177,11 +187,7 @@ public class Room implements InfoRequest
     }
 
     public Set<Occupant> getOccupants() {
-        Set<Occupant> set = new HashSet<Occupant>();
-        for (Occupant occupant : occupants.values()) {
-            set.add(occupant);
-        }
-
+        Set<Occupant> set = new HashSet<Occupant>(occupants.values());
         return Collections.unmodifiableSet(set);
     }
 

Modified: mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/EnterRoomTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/EnterRoomTestCase.java?rev=1052865&r1=1052864&r2=1052865&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/EnterRoomTestCase.java (original)
+++ mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/EnterRoomTestCase.java Sun Dec 26 10:52:53 2010
@@ -22,8 +22,10 @@ package org.apache.vysper.xmpp.modules.e
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.vysper.xml.fragment.Attribute;
 import org.apache.vysper.xml.fragment.XMLElement;
 import org.apache.vysper.xml.fragment.XMLElementBuilder;
+import org.apache.vysper.xml.fragment.XMLElementVerifier;
 import org.apache.vysper.xmpp.addressing.Entity;
 import org.apache.vysper.xmpp.modules.extension.xep0045_muc.TestSessionContext;
 import org.apache.vysper.xmpp.modules.extension.xep0045_muc.model.Affiliation;
@@ -101,11 +103,11 @@ public class EnterRoomTestCase extends A
 
     public void testEnterExistingRoom() throws Exception {
         Room room = conference.findRoom(ROOM1_JID);
-        assertEquals(0, room.getOccupants().size());
+        assertEquals(0, room.getOccupantCount());
 
         enterRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK);
 
-        assertEquals(1, room.getOccupants().size());
+        assertEquals(1, room.getOccupantCount());
         Occupant occupant = room.getOccupants().iterator().next();
 
         assertEquals(OCCUPANT1_JID, occupant.getJid());
@@ -114,12 +116,12 @@ public class EnterRoomTestCase extends A
 
     public void testEnterWithGroupchatProtocol() throws Exception {
         Room room = conference.findRoom(ROOM1_JID);
-        assertEquals(0, room.getOccupants().size());
+        assertEquals(0, room.getOccupantCount());
 
         // enter using the old groupchat protocol
         enterRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK, null, null, true);
 
-        assertEquals(1, room.getOccupants().size());
+        assertEquals(1, room.getOccupantCount());
         Occupant occupant = room.getOccupants().iterator().next();
 
         assertEquals(OCCUPANT1_JID, occupant.getJid());
@@ -144,7 +146,7 @@ public class EnterRoomTestCase extends A
         Stanza error = enterRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK);
         assertPresenceErrorStanza(error, ROOM1_JID, OCCUPANT1_JID, StanzaErrorType.AUTH, StanzaErrorCondition.FORBIDDEN);
 
-        assertEquals(0, room.getOccupants().size());
+        assertEquals(0, room.getOccupantCount());
     }
 
     public void testEnterAsNonMember() throws Exception {
@@ -153,16 +155,37 @@ public class EnterRoomTestCase extends A
         Stanza error = enterRoom(OCCUPANT1_JID, ROOM2_JID_WITH_NICK);
         assertPresenceErrorStanza(error, ROOM2_JID, OCCUPANT1_JID, StanzaErrorType.AUTH, StanzaErrorCondition.REGISTRATION_REQUIRED);
 
-        assertEquals(0, room.getOccupants().size());
+        assertEquals(0, room.getOccupantCount());
     }
 
     public void testEnterRoomWithDuplicateNick() throws Exception {
-        assertNull(enterRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK));
-        Stanza error = enterRoom(OCCUPANT2_JID, ROOM1_JID_WITH_NICK);
+        Room room1 = conference.findRoom(ROOM1_JID);
+        room1.setRewriteDuplicateNick(false); // do not rewrite existing nick, second join will fail
+        assertNull(enterRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK)); // 1st join                                   
+        Stanza error = enterRoom(OCCUPANT2_JID, ROOM1_JID_WITH_NICK); // 2nd join
 
         assertNotNull(error);
     }
 
+    public void testEnterRoomWithDuplicateNick_Rewrite() throws Exception {
+        Room room1 = conference.findRoom(ROOM1_JID);
+        room1.setRewriteDuplicateNick(true); // do rewrite nick, second join will succeed
+        assertNull(enterRoom(OCCUPANT2_JID, ROOM1_JID_WITH_NICK)); // 1st join                                   
+        Stanza error = enterRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK); // 2nd join
+        assertNull(error);
+        final Stanza stanza1 = occupant1Queue.getNext();
+        final Stanza stanza2 = occupant1Queue.getNext();
+        final XMLElementVerifier verifier = stanza2.getVerifier();
+        final X x = X.fromStanza(stanza2);
+        final List<XMLElement> statuses = x.getInnerElementsNamed("status");
+        boolean rewriteCode = false;
+        for (XMLElement status : statuses) {
+            final String code = status.getAttributeValue("code");
+            if ("210".equals(code)) rewriteCode = true;
+        }
+        assertTrue(rewriteCode);
+    }
+
     public void testEnterNonExistingRoom() throws Exception {
         Room room = conference.findRoom(ROOM2_JID);
         assertNull(room);
@@ -171,7 +194,7 @@ public class EnterRoomTestCase extends A
 
         room = conference.findRoom(ROOM2_JID);
         assertNotNull(room);
-        assertEquals(1, room.getOccupants().size());
+        assertEquals(1, room.getOccupantCount());
         Occupant occupant = room.getOccupants().iterator().next();
 
         assertEquals(OCCUPANT1_JID, occupant.getJid());
@@ -192,7 +215,7 @@ public class EnterRoomTestCase extends A
 
         // no error should be returned
         assertNull(enterRoom(OCCUPANT1_JID, ROOM2_JID_WITH_NICK, "secret", null, false));
-        assertEquals(1, room.getOccupants().size());
+        assertEquals(1, room.getOccupantCount());
     }
 
     public void testEnterWithoutPassword() throws Exception {

Modified: mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/ExitRoomTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/ExitRoomTestCase.java?rev=1052865&r1=1052864&r2=1052865&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/ExitRoomTestCase.java (original)
+++ mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/handler/ExitRoomTestCase.java Sun Dec 26 10:52:53 2010
@@ -69,7 +69,7 @@ public class ExitRoomTestCase extends Ab
 
         assertNull(exitRoom(OCCUPANT1_JID, ROOM1_JID_WITH_NICK));
 
-        assertEquals(1, room.getOccupants().size());
+        assertEquals(1, room.getOccupantCount());
         Occupant occupant = room.getOccupants().iterator().next();
 
         assertEquals(OCCUPANT2_JID, occupant.getJid());

Modified: mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java
URL: http://svn.apache.org/viewvc/mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java?rev=1052865&r1=1052864&r2=1052865&view=diff
==============================================================================
--- mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java (original)
+++ mina/vysper/trunk/server/extensions/xep0045-muc/src/test/java/org/apache/vysper/xmpp/modules/extension/xep0045_muc/model/RoomTestCase.java Sun Dec 26 10:52:53 2010
@@ -118,18 +118,18 @@ public class RoomTestCase extends TestCa
         Room room = new Room(roomJid1, "Room 1");
         room.addOccupant(occupantJid1, "Nick 1");
 
-        assertEquals(1, room.getOccupants().size());
+        assertEquals(1, room.getOccupantCount());
 
         Occupant occupant = room.getOccupants().iterator().next();
         assertEquals(occupantJid1, occupant.getJid());
         assertEquals("Nick 1", occupant.getNick());
 
         room.addOccupant(occupantJid2, "Nick 2");
-        assertEquals(2, room.getOccupants().size());
+        assertEquals(2, room.getOccupantCount());
 
         room.removeOccupant(occupantJid1);
 
-        assertEquals(1, room.getOccupants().size());
+        assertEquals(1, room.getOccupantCount());
 
         occupant = room.getOccupants().iterator().next();
         assertEquals(occupantJid2, occupant.getJid());