Author: VenkatramanSubramanian Date: 2009-01-14 14:29:18 -0500 (Wed, 14 Jan 2009) New Revision: 1482
Modified: trunk/concordance/examples/register.py Log: Added methods for user registration Modified: trunk/concordance/examples/register.py =================================================================== --- trunk/concordance/examples/register.py 2009-01-14 06:23:04 UTC (rev 1481) +++ trunk/concordance/examples/register.py 2009-01-14 19:29:18 UTC (rev 1482) @@ -27,8 +27,45 @@ import concordance import xml.etree.cElementTree as ElementTree -class regcore(concordance.Core) : - def getquery(self, query, out_root) : +#All the Users are stored in a Dictionary/Hash(in-memory) in a session +#they are NOT (de)serialized +UserDB = {} + +class User(object): + ''' + Class to store the User information + ''' + def __init__(self,username, email, fname, lname, pwd): + self.username = username + self.email = email + self.fname = fname + self.lname = lname + self.pwd = pwd + #Mothers Maiden Name can also be added + +class InBandRegistration(concordance.Core) : + def createNode(self, parent_node,tag_name, tag_val): + ''' + Method that creates a node given its name and value; it is attached to its parent + TO-DO : Make this as th standard way of creating a 'simple'node; can this be moved to a better OO paradigm? + ''' + temp_node = ElementTree.SubElement(parent_node, tag_name) + temp_node.text = tag_val + + def failedError(self, err_code, err_type, err_desc, input): + ''' + Error Information to be added when something fails or errors out + ''' + out_error = ElementTree.SubElement(input, 'error') + out_error.attrib['code'] = err_code + out_error.attrib['type'] = err_type + ElementTree.SubElement(out_error, err_desc) + out_error[0].attrib['xmlns'] ='urn:ietf:params:xml:ns:xmpp-stanzas' + + def regScreen(self, query, out_root) : + ''' + Host Returns Registration Fields to Entity + ''' if query.tag == '{jabber:iq:register}query' : out_query = ElementTree.SubElement(out_root, 'query') out_query.attrib['xmlns'] = 'jabber:iq:register' @@ -38,14 +75,178 @@ You'll just need to complete this registration form with your \ chosen name, password, and an email address we can reach you at. -There isn't much more to this server than this form, so enjoy!''' +There isn't much more to this server than a simple registration, so enjoy!''' for field in ['username', 'password', 'first', 'last', 'email'] : ElementTree.SubElement(out_query, field) + def validateRegistration(self, input, out_root): + ''' + When Registration Fails (USERNAME CONFLICT) + Also checks for Missing Information + ''' + out_root.attrib['type'] = 'error' - def clientHandle(self, session, input) : + #construct the 'query' node and its children + out_query = ElementTree.SubElement(out_root, 'query') + out_query.attrib['xmlns'] = 'jabber:iq:register' + + #Checks for non-null Email, Username and Password fields + i= "" + error_code = 0 + for qnode in input: + for r in qnode: + tag = r.tag + if tag == '{jabber:iq:register}username': + if r.text: + #Checks whether the user has already registered or not - this is done by a lookup for email in the UserDB dict + if r.text in UserDB: + self.createNode(out_query,'username',r.text) + error_code = 1 #set to 1 for USER_CONFLICT + print("User already Registered") + else: + error_code = 2 + break + elif tag == '{jabber:iq:register}password': + if r.text: + self.createNode(out_query,'password',r.text) + else: + error_code = 2 + break + elif tag == '{jabber:iq:register}email': + if r.text: + self.createNode(out_query,'email',r.text) + else: + error_code = 2 + break + + if error_code == 0: + UserDB[r.text]=r.text # Save usernames alone + #TO-DO : change this to include the record as the value + self.successReg( input, out_root) + elif error_code == 1: + #User already exists with the same email Id - hence Host generates a 'conflict' message + #Q : Do we need to check the correspondance of all fields for duplicate user; presently only username is checked + self.failedError('409', 'cancel', 'conflict', out_root) + elif error_code == 2 : + #Information is missing - hence Host generates a 'not-acceptable' message + self.failedError('406', 'modify', 'not-acceptable', out_root) + + def successCancel(self, input, out_root): + ''' + Host Informs Entity of Successful Cancellation + ''' + out_root.attrib['to']='' #TO-DO ??? to include the emailid + + def createField(self, parent_node,type, var, value, label = None, is_required = None): + ''' + A generic method which creates a 'field' node with the supplied attribute and type information + ''' + field = ElementTree.SubElement(parent_node, 'field') + if type: + field.attrib['type'] = type + #else : Should throw an error TO-DO??? + + if var: + field.attrib['var'] = var + #else : Should throw an error TO-DO??? + + if label: + field.attrib['label'] = label + if is_required : + ElementTree.SubElement(field, 'required') + if value: + val = ElementTree.SubElement(field, 'value') + val.text = value + + def cancelForm(self, input, out_root): + ''' + Server Returns Cancellation Form With Error + Server asks for previous gathered information to confirm cancellation + ''' + #construct the 'query' node; 'x' will be its child + out_query = ElementTree.SubElement(out_root, 'query') + out_query.attrib['xmlns'] = 'jabber:iq:register' + + #construct the 'x' node; various fields and other info will be its children + out_x = ElementTree.SubElement(out_query, 'x') + out_x.attrib['xmlns'] = 'jabber:x:data' + out_x.attrib['type'] = 'form' + title = ElementTree.SubElement(out_x, 'title') + title.text = 'Password Change' + instructions = ElementTree.SubElement(x, 'instructions') + instructions.text = 'Use this form to cancel your registration.' + self.createField(x, 'hidden', 'FORM_TYPE', 'jabber:iq:register:cancel') + self.createField(x, 'text-single', 'username', None , 'Username', True) + self.createField(x, 'text-private', 'password', None, 'Password', True) + self.createField(x, 'text-single', 'x-mmn', None, 'Mother's Maiden Name', True) + + #construct the 'error' node - this is a child to 'iq' and a sibling of 'query' + self.failedError('405', 'cancel', 'not-allowed', out_root) + + def processCancelForm(self, input, out_root): + ''' + Method checks the validity of the password provided and the answer for the safety Q(mother's maiden name); and then + removes the registration of the user from the server + TO DO : Work in Progress + ''' + pass + + def successReg(self, input, out_root): + ''' + Host Informs Entity of Successful Registration + Note: 'input' is being passed to accomodate any future enhancements, otherwise it is not required + ''' + out_root.attrib['type'] = 'result' + + def successPwdChange(self, input, out_root): + ''' + Host Informs Client of Successful Password Change + Note: 'input' is being passed to accomodate any future enhancements, otherwise it is not required + ''' + out_root.attrib['type']='result' + + def pwdChangeFormError(self, input, out_root): + '''Server Returns Password Change Form With Error + ''' + #construct 'query' node; 'x' will be its child + out_query = ElementTree.SubElement(out_root, 'query') + out_query.attrib['xmlns'] = 'jabber:iq:register' + + #construct 'x' node + out_x = ElementTree.SubElement(out_query, 'x') + out_x.attrib['xmlns'] = 'jabber:x:data' + out_x.attrib['type'] = 'form' + #construct children of 'x' + title = ElementTree.SubElement(out_x, 'title') + title.text = 'Password Change' + instructions = ElementTree.SubElement(x, 'instructions') + instructions.text = 'Use this form to change your password.' + self.createField(x, 'hidden', 'FORM_TYPE', 'jabber:iq:register:changepassword') + self.createField(x, 'text-single', 'username', None , 'Username', True) + self.createField(x, 'text-private', 'old_password', None, 'Old Password', True) + self.createField(x, 'text-private', 'password', None, 'New Password', True) + self.createField(x, 'text-single', 'x-mmn', None, 'Mother's Maiden Name', True) + + #construct the 'error' node + self.failedError('401', 'modify', 'not-authorized', out_root) + + def savePwdChange(self, input, out_root): + ''' + Method to save the password provided by the user + Method also checks whether the password saved in UserDB and old_password match or not ; + and also the check for safety Q(mother's maiden name) + TO-DO : Work Under Process + ''' + pass + + + def clientHandle(self, session, message) : + ''' + this method keeps waiting for a message and dispatches it to the suitabe method after filtering + ''' # get xml root of input - in_root = ElementTree.fromstring(input) + print("C: %s" % message) + in_root = ElementTree.fromstring(message) # this example only replies to <iq/> requests if in_root.tag != '{jabber:client}iq' : @@ -54,19 +255,19 @@ out_root = ElementTree.Element('iq') out_root.attrib['id'] = in_root.attrib['id'] - # if type="get" if in_root.attrib['type'] == 'get' : out_root.attrib['type'] = 'result' - for query in in_root : - self.getquery(query, out_root) - + self.regScreen(query, out_root) + elif in_root.attrib['type'] == 'set': + self.validateRegistration(in_root, out_root) + print("New Client - Chck User") else : return "" - print("C: %s" % input) print("S: %s" % ElementTree.tostring(out_root)) return ElementTree.tostring(out_root) -rc = regcore() -rc() +#clientHandle just waits for any events from the client/entity +regcore=InBandRegistration() +regcore() _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn