LOC-3 Room Owners can now kick (and ban) users from the room
LOC-3 Room Owners can now kick (and ban) users from the room

To kick a user out of the room, the owner can do

/kick [user]

To kick them and remove their ability to return, do

/ban [user]

--- a/client/LocalChatClient.py
+++ b/client/LocalChatClient.py
@@ -238,6 +238,35 @@
         
         return True
 
+
+
+    def kickUser(self,user,ban=False):
+        ''' Kick a user out of the room
+        '''
+        
+        action = 'banUser'
+        
+        if not ban:
+            action = 'kickUser'
+        
+        payload = {"roomName": self.room, 
+                   "user": self.user,
+                   "kick": user
+                   }
+        
+        request = {"action":action,
+                   "payload": json.dumps(payload)
+                   }    
+                
+        resp = self.sendRequest(request)
+
+        if resp == "BROKENLINK" or resp['status'] != "ok":
+            return False
+        
+        return True
+
+        
+        
 
     def sendRequest(self,data):
         data = json.dumps(data)
@@ -295,11 +324,6 @@
     def __init__(self,quit_commands=['q','quit','exit'], help_commands=['help','?', 'h']):
         self._quit_cmd=quit_commands
         self._help_cmd=help_commands
-        self._controlcommands = [
-            "join","leave","room"
-            
-            
-            ]
         
     def __call__(self,line):
         global msg
@@ -311,6 +335,18 @@
             # It's a command
             cmd = cmd[1:]
             
+            
+            if cmd == "ban":
+                # /kick [user]
+                
+                if len(args) < 1:
+                    raise InvalidCommand(line)
+                
+                
+                m = msg.kickUser(args[0],True)
+                return
+                        
+            
             if cmd == "join":
                 # /join [username] [room] [password]
                 
@@ -321,6 +357,18 @@
                 if not msg.joinRoom(args[0],args[1],args[2]):
                     raise UnableTo('join',line)
                 return
+            
+            
+            if cmd == "kick":
+                # /kick [user]
+                
+                if len(args) < 1:
+                    raise InvalidCommand(line)
+                
+                
+                m = msg.kickUser(args[0])
+                return
+            
             
             if cmd == "leave":
                 # /leave

--- a/server/LocalChat.py
+++ b/server/LocalChat.py
@@ -122,9 +122,15 @@
         
         elif reqjson['action'] == "leaveRoom":
             return self.processleaveRoom(reqjson)
+
+        elif reqjson['action'] == "banUser":
+            return self.kickUser(reqjson,True)
         
         elif reqjson['action'] == "inviteUser":
             return self.inviteUser(reqjson)
+        
+        elif reqjson['action'] == "kickUser":
+            return self.kickUser(reqjson,False)
         
         elif reqjson['action'] == 'sendMsg':
             return self.sendMsg(reqjson)
@@ -215,6 +221,56 @@
                 "status":'ok'
             }
         
+    
+    
+    def kickUser(self,reqjson,ban=False):
+        ''' Kick a user out of room
+        
+        Default is just to boot them out, but can also remove their authorisation to enter
+        '''
+        
+        if "roomName" not in reqjson['payload'] or "user" not in reqjson['payload'] or "kick" not in reqjson['payload']:
+            return 400
+        
+        room = self.getRoomID(reqjson['payload']["roomName"])
+        
+        if not room:
+            return 400
+        
+        
+        # Check the requesting user is the admin
+        self.cursor.execute("SELECT * from rooms where id=? and owner=?",(room,reqjson["payload"]["user"]))
+        n = self.cursor.fetchone()
+        
+        if not n:
+            return 403
+        
+        
+        
+        self.cursor.execute("UPDATE users set active=0 where room=? and username=?",(room,reqjson["payload"]["kick"]))
+        m = {
+                "user":"SYSTEM",
+                "text":"User %s kicked %s from the room" % (reqjson['payload']['user'],reqjson['payload']['kick'])
+            }
+        
+        self.cursor.execute("INSERT INTO messages (ts,room,msg) VALUES (?,?,?)",(time.time(),room,json.dumps(m)))
+        msgid = self.cursor.lastrowid
+        self.conn.commit()
+                    
+        if ban:
+            # If we're banning them, also need to disinvite them
+            self.cursor.execute("DELETE from users where room=? and username=?",(room,reqjson["payload"]["kick"]))
+            m = {
+                    "user":"SYSTEM",
+                    "text":"User %s banned %s from the room" % (reqjson['payload']['user'],reqjson['payload']['kick'])
+                }
+            
+            self.cursor.execute("INSERT INTO messages (ts,room,msg) VALUES (?,?,?)",(time.time(),room,json.dumps(m)))
+            self.conn.commit()
+        
+        return { "status" : "ok" }
+    
+    
     
     
     def processjoinRoom(self,reqjson):