2100c2219f83 — cedricbonhomme 11 years ago
Added login of the client, connection to the SPADE platform. The ReceiveMessage behavior of the client is launched after the login of the client.
M source/authenticationAgent.py +10 -2
@@ 27,8 27,8 @@ under certain conditions; type `show c' 
 
 __author__ = "Cedric Bonhomme"
 __version__ = "$Revision: 0.1 $"
-__date__ = "$Date: 2009/12/27 $"
-__copyright__ = "Copyright (c) 2009 Cedric Bonhomme"
+__date__ = "$Date: 2010/01/04 $"
+__copyright__ = "Copyright (c) 2010 Cedric Bonhomme"
 __license__ = "GPLv3"
 
 import os

          
@@ 86,6 86,14 @@ class AuthenticationAgent(spade.Agent.Ag
                 elif command[0] == "signout":
                     pass
 
+                elif command[0] == "login":
+                    if command[2] == xmlParser.get_password(command[1]):
+                        ontology = xmlParser.get_ontology(command[1])
+                        self.myAgent.outgoing_message = "authentication_success:" +\
+                                                            ontology
+                    else:
+                        self.myAgent.outgoing_message = "authentication_failed"
+
                 elif command[0] == "addinterlocutor":
                     pubkey = str(xmlParser.get_pub_key(command[1]))
                     ontology = str(xmlParser.get_ontology(command[1]))

          
M source/clientAgent.py +16 -6
@@ 27,8 27,8 @@ under certain conditions; type `show c' 
 
 __author__ = "Cedric Bonhomme"
 __version__ = "$Revision: 0.1 $"
-__date__ = "$Date: 2009/12/17 $"
-__copyright__ = "Copyright (c) 2009 Cedric Bonhomme"
+__date__ = "$Date: 2010/01/04 $"
+__copyright__ = "Copyright (c) 2010 Cedric Bonhomme"
 __license__ = "GPLv3"
 
 import os

          
@@ 53,6 53,8 @@ class ClientAgent(spade.Agent.Agent):
             """
             print "Starting", self.__class__.__name__, "behaviour"
 
+            self.myAgent.register()
+
         def _process(self):
             """
             Analyse and process the anwser.

          
@@ 74,6 76,15 @@ class ClientAgent(spade.Agent.Agent):
                 elif command[0] == "already_registered":
                     self.myAgent.gui.show_info("Username already used !")
 
+                elif command[0] == "authentication_success":
+                    self.myAgent.ontology = command[1]
+                    self.myAgent.launch_behaviour_client()
+                    self.myAgent.gui.show_info("Authentication success")
+
+                elif command[0] == "authentication_failed":
+                    self.myAgent.gui.show_info("Authentication failed")
+
+
     class SendMessageToAuthenticator(spade.Behaviour.OneShotBehaviour):
         """
         This class is in charge of sending request to the authentication agent.

          
@@ 122,7 133,6 @@ class ClientAgent(spade.Agent.Agent):
             """
             print "Starting", self.__class__.__name__, "behaviour"
 
-            self.myAgent.register()
 
         def _process(self):
             """

          
@@ 202,17 212,17 @@ class ClientAgent(spade.Agent.Agent):
         self.blocked_sender = []
 
 
-    def launchBehaviours(self, ontology):
+    def launch_behaviour_client(self):
         """
         """
         cooking_template = spade.Behaviour.ACLTemplate()
-        cooking_template.setOntology(ontology)
+        cooking_template.setOntology(self.myAgent.ontology)
         mt = spade.Behaviour.MessageTemplate(cooking_template)
         # Add the behaviour WITH the template
         receive_messabe_behaviour = self.ReceiveMessage()
         self.addBehaviour(receive_messabe_behaviour, mt)
 
-
+    def launch_behaviour_authenticator(self):
         cooking_template = spade.Behaviour.ACLTemplate()
         cooking_template.setOntology("authentication")
         mt = spade.Behaviour.MessageTemplate(cooking_template)

          
M source/configurations/clients_informations.xml +1 -1
@@ 1,1 1,1 @@ 
-<?xml version="1.0" ?><clients><client><name>bob</name><password>dfe71540d0c478f2e15a07b787858a74e7164aea</password><ontology>ontoBob</ontology><pubkey>11891137969571802028160076616668027898285222830850142303479185197334793066019-22073793352649156854571531060839366625429482055701440248826259391365612792907</pubkey></client><client><name>alice</name><password>dfe71540d0c478f2e15a07b787858a74e7164aea</password><ontology>ontoAlice</ontology><pubkey>2941100472169965883204283263959251670882189892665487919803041644085000085601-6927945601740986627547277880776736030682638771076254911141084848009805380167</pubkey></client></clients>
  No newline at end of file
+<?xml version="1.0" ?><clients><client><name>bob</name><password>5ed25af7b1ed23fb00122e13d7f74c4d8262acd8</password><ontology>ontoBob</ontology><pubkey>38723395226133652871487606996660680568884218896052816620080482121786369165077-44796142063839315885604999554134286106416435926357041352384991407956854635383</pubkey></client><client><name>alice</name><password>92ef57ba40706594b46425705e989cbc256d9724</password><ontology>ontoAlice</ontology><pubkey>4226379839617916115200972967138836288667954226038144740594176117603282128143-96979420560157444204666866837285905997510158302326814682483261762443509495551</pubkey></client></clients>
  No newline at end of file

          
M source/simpleGui.py +137 -25
@@ 28,8 28,8 @@ under certain conditions; type `show c' 
 
 __author__ = "Cedric Bonhomme"
 __version__ = "$Revision: 0.1 $"
-__date__ = "$Date: 2009/12/27 $"
-__copyright__ = "Copyright (c) 2009 Cedric Bonhomme"
+__date__ = "$Date: 2010/01/04 $"
+__copyright__ = "Copyright (c) 2010 Cedric Bonhomme"
 __license__ = "GPLv3"
 
 import time

          
@@ 75,7 75,7 @@ labelTextStyle = { \
 }
 
 class SimpleGui(object):
-    """Simple GUI for pyCHatter.
+    """Simple GUI for pyChatter.
     """
     def __init__(self, name, agent_host, agent_ontology, agent_pubkey):
         """

          
@@ 86,6 86,7 @@ class SimpleGui(object):
         self.ontology = agent_ontology
         self.pubkey = agent_pubkey
         self.my_rsa_keys = None
+        self.client_agent = None
 
         self.master = Tk()
         self.master.protocol("WM_DELETE_WINDOW", self.onClose)

          
@@ 99,19 100,18 @@ class SimpleGui(object):
         self.tuxy_thread.setDaemon(True)
         self.tuxy_thread.start()
 
-        # create the menu
+        # Create the menu
         self.__create_menu()
 
-
-        """Widget Text avec une ScrollBar pour la discussion"""
-        self.conversation_zone = Text(self.master, state=DISABLED,**fieldParams)
+        # Text widget with a scrollBar for the conversation zone
+        self.conversation_zone = Text(self.master, state = DISABLED, **fieldParams)
         self.scrollbar = Scrollbar(self.master, orient = VERTICAL)
         self.scrollbar.config(command = self.conversation_zone.yview)
         self.scrollbar.grid(column = 3, row = 1, sticky = S + N)
         self.conversation_zone.config(yscrollcommand = self.scrollbar)
         self.conversation_zone.grid(row = 1, columnspan = 3)
 
-        """Widget Text avec une ScrollBar pour le message à envoyer"""
+        # Text widget with scrollbar for the message to send
         self.message_to_send = Text(self.master, **textParams)
         self.barreM = Scrollbar(self.master, orient = VERTICAL)
         self.barreM.config(command = self.message_to_send.yview)

          
@@ 125,13 125,6 @@ class SimpleGui(object):
         # Create the right panel
         self.__create_right_panel()
 
-        # Create the agent for the local client.
-        self.client_agent = clientAgent.ClientAgent( \
-                    self.name.lower() + "@" + self.agent_host, "secret")
-        self.client_agent.start()
-        self.client_agent.gui = self
-        self.client_agent.launchBehaviours(self.ontology)
-
         # Load local RSA keys
         self.load_rsa_keys()
 

          
@@ 148,9 141,16 @@ class SimpleGui(object):
         # File menu
         filemenu = Menu(self.menu, tearoff = 0)
         self.menu.add_cascade(label = "File", menu = filemenu)
+        filemenu.add_command(label = "Connect to platform", \
+                                command = self.connect_to_platform)
+        filemenu.add_command(label = "Disconnect from platform", \
+                                command = self.disconnect_from_platform)
+        filemenu.add_separator()
         filemenu.add_command(label = "Signin", command = self.signin)
         filemenu.add_command(label = "Signout")
         filemenu.add_separator()
+        filemenu.add_command(label = "Login", command = self.login)
+        filemenu.add_separator()
         niveau = Menu(self.menu, tearoff = 0)
         filemenu.add_cascade(label = "State", menu = niveau)
         niveau.add_command(label = "Free to chat")

          
@@ 204,6 204,74 @@ class SimpleGui(object):
             print e # exceptions coming from tuxdroid module
             self.tuxy = None
 
+    def connect_to_platform(self):
+        """
+        """
+        def execute():
+            try:
+                username = str(username_entry.get())
+                address = str(spade_address_entry.get())
+                password = str(spade_password_entry.get())
+            except ValueError:
+                tkMessageBox.showerror('Error', 'Bad entry')
+                return
+
+            self.client_agent = clientAgent.ClientAgent( \
+                        username.lower() + "@" + address, password)
+            self.client_agent.start()
+            self.client_agent.gui = self
+
+            self.client_agent.launch_behaviour_authenticator()
+
+            msg.destroy()
+
+        if self.client_agent != None:
+            self.show_info('Already connected to the SPADE platform.')
+            return
+
+        msg = Toplevel(self.master)
+        msg.title('Connection to the SPADE platform')
+        msg.resizable(height = False, width = False)
+
+        Label(msg, text='Username : ').grid(row = 0, column = 0)
+        username_entry = Entry(msg)
+        username_entry.grid(row = 0, column = 1, pady = 2)
+        username_entry.insert(0, self.name.lower())
+        username_entry.focus_set()
+
+        Label(msg, text='SPADE host address : ').grid(row = 1, column = 0)
+        spade_address_entry = Entry(msg)
+        spade_address_entry.grid(row = 1, column = 1, pady = 2)
+        spade_address_entry.insert(0, self.agent_host)
+
+        Label(msg, text='SPADE password : ').grid(row = 2, column = 0)
+        spade_password_entry = Entry(msg)
+        spade_password_entry.grid(row = 2, column = 1, pady = 2)
+        spade_password_entry.insert(0, "secret")
+
+        Button(msg, text="OK", \
+            command = execute).grid(row = 3, columnspan = 2, pady = 2)
+
+        ## sets the focus window (for Windows)
+        msg.focus_set()
+        ## force events to go to this window
+        msg.grab_set()
+        ## window remains above its parent window
+        msg.transient(self.master)
+        ## displays the window and waits for its closure
+        msg.wait_window(msg)
+
+
+    def disconnect_from_platform(self):
+        """
+        """
+        try:
+            self.client_agent.tearDown()
+            self.client_agent = None
+        except AttributeError:
+            # agent not started
+            self.show_info('Not connected to the SPADE platform.')
+
     def signin(self):
         """Signin Window
         Allows the client to register itself at the main server.

          
@@ 254,7 322,7 @@ class SimpleGui(object):
         msg.title('Signin')
         msg.resizable(height = False, width = False)
 
-        Label(msg, text='Username : ', state=DISABLED).grid(row = 0, column = 0)
+        Label(msg, text='Username : ', state = DISABLED).grid(row = 0, column = 0)
         username_entry = Entry(msg)
         username_entry.grid(row = 0, column = 1, pady = 2)
         username_entry.insert(0, self.name.lower())

          
@@ 294,13 362,56 @@ class SimpleGui(object):
         """
         pass
 
+    def login(self):
+        def execute():
+            try:
+                password = password_entry.get()
+            except ValueError:
+                tkMessageBox.showerror('Error', 'Bad entry')
+                return
+
+            sha1_hash = hashlib.sha1()
+            sha1_hash.update(password)
+            hashed_passwd = sha1_hash.hexdigest()
+
+            self.client_agent.outgoing_message = "login:" + \
+                self.name.lower() + ":" + hashed_passwd
+
+            # send the answer to the authentication agent
+            self.client_agent.addBehaviour(self.client_agent.SendMessageToAuthenticator(), None)
+
+            msg.destroy()
+
+        msg = Toplevel(self.master)
+        msg.title('Login')
+        msg.resizable(height = False, width = False)
+
+        Label(msg, text='Enter your password : ').grid(row = 0, column = 0)
+        password_entry = Entry(msg)
+        password_entry.grid(row = 1, column = 0, pady = 2)
+        password_entry.focus_set()
+
+        Button(msg, text="OK", \
+            command = execute).grid(row = 5, columnspan = 2, pady = 2)
+
+        ## sets the focus window (for Windows)
+        msg.focus_set()
+        ## force events to go to this window
+        msg.grab_set()
+        ## window remains above its parent window
+        msg.transient(self.master)
+        ## displays the window and waits for its closure
+        msg.wait_window(msg)
 
     def display_client_list(self):
         """Display the list of client in a new window.
         """
-
-        list_of_clients = self.client_agent.search_agent_into_df( \
-                                                service_type = "client_agent")
+        try:
+            list_of_clients = self.client_agent.search_agent_into_df( \
+                                                    service_type = "client_agent")
+        except AttributeError:
+            self.show_info('You are not connected to the SPADE platform.')
+            return
 
         msg = Toplevel(self.master)
         msg.title('Available clients')

          
@@ 387,10 498,6 @@ class SimpleGui(object):
             # selected client. The answer is managed in the
             # method "add_client"
 
-
-            self.client_agent.gui = self
-            self.client_agent.ontology = self.ontology
-
             #tkMessageBox.showinfo('Information', 'Connected with ' + client)
         else:
             # If the selected client is already an interlocutor

          
@@ 540,8 647,13 @@ class SimpleGui(object):
     def onClose(self):
         """Close the client.
         """
-        self.client_agent.tearDown()
-        self.master.destroy()
+        try:
+            self.client_agent.tearDown()
+        except AttributeError:
+            # agent not started
+            pass
+        finally:
+            self.master.destroy()
 
     def about(self):
         """

          
M source/tuxdroid.py +4 -3
@@ 28,9 28,10 @@ under certain conditions; type `show c' 
 """
 
 __author__ = "Cedric Bonhomme"
-__date__ = "$Date: 2009/12/21 06:46 $"
-__copyright__ = "Copyright (c) 2009 Cedric Bonhomme"
-__license__ = "GPL 3"
+__version__ = "$Revision: 0.1 $"
+__date__ = "$Date: 2010/01/04 $"
+__copyright__ = "Copyright (c) 2010 Cedric Bonhomme"
+__license__ = "GPL v3"
 
 try:
     from tuxisalive.api import *

          
M source/xmlParser.py +1 -1
@@ 27,7 27,7 @@ under certain conditions; type `show c' 
 
 __author__ = "Cedric Bonhomme"
 __version__ = "$Revision: 0.1 $"
-__date__ = "$Date: 2009/12/14 $"
+__date__ = "$Date: 2010/01/04 $"
 __copyright__ = "Copyright (c) 2010 Cedric Bonhomme"
 __license__ = "GPLv3"