| Home | Trees | Indices | Help | 
 | 
|---|
|  | 
  1  # 
  2  # (C) Copyright 2005-2006 Jacek Konieczny <jajcus@jajcus.net> 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU Lesser General Public License Version 
  6  # 2.1 as published by the Free Software Foundation. 
  7  # 
  8  # This program is distributed in the hope that it will be useful, 
  9  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 11  # GNU Lesser General Public License for more details. 
 12  # 
 13  # You should have received a copy of the GNU Lesser General Public 
 14  # License along with this program; if not, write to the Free Software 
 15  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 16  # 
 17   
 18  """In-band registration (jabber:iq:register) handling. 
 19   
 20  Normative reference: 
 21    - `JEP 77 <http://www.jabber.org/jeps/jep-0077.html>`__ 
 22  """ 
 23   
 24  __revision__="$Id: delay.py 567 2005-03-29 20:08:55Z jajcus $" 
 25  __docformat__="restructuredtext en" 
 26   
 27  import libxml2 
 28  import logging 
 29   
 30  from pyxmpp.utils import to_utf8,from_utf8 
 31  from pyxmpp.xmlextra import get_node_ns_uri 
 32  from pyxmpp.objects import StanzaPayloadObject 
 33  from pyxmpp.xmlextra import xml_element_iter 
 34   
 35  from pyxmpp.jabber.dataforms import DATAFORM_NS, Form 
 36   
 37  REGISTER_NS="jabber:iq:register" 
 38   
 39  legacy_fields = { 
 40          "username": ("text-single", u"Account name associated with the user"), 
 41          "nick": ("text-single", u"Familiar name of the user"), 
 42          "password": ("text-private", u"Password or secret for the user"), 
 43          "name": ("text-single", u"Full name of the user"), 
 44          "first": ("text-single", u"First name or given name of the user"), 
 45          "last": ("text-single", u"Last name, surname, or family name of the user"), 
 46          "email": ("text-single", u"Email address of the user"), 
 47          "address": ("text-single", u"Street portion of a physical or mailing address"), 
 48          "city": ("text-single", u"Locality portion of a physical or mailing address"), 
 49          "state": ("text-single", u"Region portion of a physical or mailing address"), 
 50          "zip": ("text-single", u"Postal code portion of a physical or mailing address"), 
 51          "phone": ("text-single", u"Telephone number of the user"), 
 52          "url": ("text-single", u"URL to web page describing the user"), 
 53          "date": ("text-single", u"Some date (e.g., birth date, hire date, sign-up date)"), 
 54          "misc": ("text-single", u"Free-form text field (obsolete)"), 
 55          "text": ("text-single", u"Free-form text field (obsolete)"), 
 56          "key": ("text-single", u"Session key for transaction (obsolete)"), 
 57          } 
 58   
 60      """ 
 61      Delayed delivery tag. 
 62   
 63      Represents 'jabber:iq:register' (JEP-0077) element of a Jabber <iq/> stanza. 
 64   
 65      Please note that it is recommended to use `get_form` and `submit_form` records 
 66      instead of accessing the `form` and legacy fields directly. This way both 
 67      legacy and Data Forms registration would work transparently to the application. 
 68   
 69      :Ivariables: 
 70          - `form`: registration form (when available) 
 71          - `registered`: `True` if entity is already registered 
 72          - `instrutions`: Registration instructions (legacy protocol) 
 73          - `username`: Username field (legacy protocol) 
 74          - `nick`: Nickname (legacy protocol) 
 75          - `password`: Password (legacy protocol) 
 76          - `name`: Name field (legacy protocol) 
 77          - `first`: First name field (legacy protocol) 
 78          - `last`: Last name field (legacy protocol) 
 79          - `email`: E-mail field (legacy protocol) 
 80          - `address`: Address field (legacy protocol) 
 81          - `city`: City field (legacy protocol) 
 82          - `state`: State field (legacy protocol) 
 83          - `zip`: ZIP code field (legacy protocol) 
 84          - `phone`: Phone field (legacy protocol) 
 85          - `url`: URL field (legacy protocol) 
 86          - `date`: Date field (legacy protocol) 
 87          - `misc`: Misc field (legacy protocol, obsolete) 
 88          - `text`: Text field (legacy protocol, obsolete) 
 89          - `key`: Key field (legacy protocol, obsolete) 
 90          - `remove`: `True` when the account should be removed 
 91      :Types: 
 92          - `form`: `pyxmpp.jabber.dataforms.Form` 
 93          - `registered`: `bool` 
 94          - `instrutions`: `unicode` 
 95          - `username`: `unicode` 
 96          - `nick`: `unicode` 
 97          - `password`: `unicode` 
 98          - `name`: `unicode` 
 99          - `first`: `unicode` 
100          - `last`: `unicode` 
101          - `email`: `unicode` 
102          - `address`: `unicode` 
103          - `city`: `unicode` 
104          - `state`: `unicode` 
105          - `zip`: `unicode` 
106          - `phone`: `unicode` 
107          - `url`: `unicode` 
108          - `date`: `unicode` 
109          - `misc`: `unicode` 
110          - `text`: `unicode` 
111          - `key`: `unicode` 
112          - `remove`: `True` when the account should be removed 
113      """ 
114   
115      xml_element_name = "query" 
116      xml_element_namespace = REGISTER_NS 
117   
119          """ 
120          Initialize the `Register` object. 
121   
122          :Parameters: 
123              - `xmlnode`: an optional XML node to parse. 
124          :Types: 
125              - `xmlnode`: `libxml2.xmlNode` 
126          """ 
127          self.__logger=logging.getLogger("pyxmpp.jabber.Register") 
128          self.form = None 
129          self.registered = False 
130          self.instructions = None 
131          self.remove = False 
132          for f in legacy_fields: 
133              setattr(self, f, None) 
134          if isinstance(xmlnode,libxml2.xmlNode): 
135              self.__from_xml(xmlnode) 
136   
138          """Initialize `Register` from an XML node. 
139   
140          :Parameters: 
141              - `xmlnode`: the jabber:x:register XML element. 
142          :Types: 
143              - `xmlnode`: `libxml2.xmlNode`""" 
144   
145          self.__logger.debug("Converting jabber:iq:register element from XML") 
146          if xmlnode.type!="element": 
147              raise ValueError,"XML node is not a jabber:iq:register element (not an element)" 
148          ns=get_node_ns_uri(xmlnode) 
149          if ns and ns!=REGISTER_NS or xmlnode.name!="query": 
150              raise ValueError,"XML node is not a jabber:iq:register element" 
151   
152          for element in xml_element_iter(xmlnode.children): 
153              ns = get_node_ns_uri(element) 
154              if ns == DATAFORM_NS and element.name == "x" and not self.form: 
155                  self.form = Form(element) 
156              elif ns != REGISTER_NS: 
157                  continue 
158              name = element.name 
159              if name == "instructions" and not self.instructions: 
160                  self.instructions = from_utf8(element.getContent()) 
161              elif name == "registered": 
162                  self.registered = True 
163              elif name == "remove": 
164                  self.remove = True 
165              elif name in legacy_fields and not getattr(self, name): 
166                  value = from_utf8(element.getContent()) 
167                  if value is None: 
168                      value = u"" 
169                  self.__logger.debug(u"Setting legacy field %r to %r" % (name, value)) 
170                  setattr(self, name, value) 
171   
173          """Complete the XML node with `self` content. 
174   
175          :Parameters: 
176              - `xmlnode`: XML node with the element being built. It has already 
177                right name and namespace, but no attributes or content. 
178              - `doc`: document to which the element belongs. 
179          :Types: 
180              - `xmlnode`: `libxml2.xmlNode` 
181              - `doc`: `libxml2.xmlDoc`""" 
182          ns = xmlnode.ns() 
183          if self.instructions is not None: 
184              xmlnode.newTextChild(ns, "instructions", to_utf8(self.instructions)) 
185          if self.form: 
186              self.form.as_xml(xmlnode, doc) 
187          if self.remove: 
188              xmlnode.newChild(ns, "remove", None) 
189          else: 
190              if self.registered: 
191                  xmlnode.newChild(ns, "registered", None) 
192              for field in legacy_fields: 
193                  value = getattr(self, field) 
194                  if value is not None: 
195                      xmlnode.newTextChild(ns, field, to_utf8(value)) 
196   
198          """Return Data Form for the `Register` object. 
199   
200          Convert legacy fields to a data form if `self.form` is `None`, return `self.form` otherwise. 
201   
202          :Parameters: 
203              - `form_type`: If "form", then a form to fill-in should be 
204                returned. If "sumbit", then a form with submitted data. 
205          :Types: 
206              - `form_type`: `unicode` 
207   
208          :return: `self.form` or a form created from the legacy fields 
209          :returntype: `pyxmpp.jabber.dataforms.Form`""" 
210   
211          if self.form: 
212              if self.form.type != form_type: 
213                  raise ValueError, "Bad form type in the jabber:iq:register element" 
214              return self.form 
215   
216          form = Form(form_type, instructions = self.instructions) 
217          form.add_field("FORM_TYPE", [u"jabber:iq:register"], "hidden") 
218          for field in legacy_fields: 
219              field_type, field_label = legacy_fields[field] 
220              value = getattr(self, field) 
221              if value is None: 
222                  continue 
223              if form_type == "form": 
224                  if not value: 
225                      value = None 
226                  form.add_field(name = field, field_type = field_type, label = field_label, 
227                          value = value, required = True) 
228              else: 
229                  form.add_field(name = field, value = value) 
230          return form 
231   
233          """Make `Register` object for submitting the registration form. 
234   
235          Convert form data to legacy fields if `self.form` is `None`. 
236   
237          :Parameters: 
238              - `form`: The form to submit. Its type doesn't have to be "submit" 
239                (a "submit" form will be created here), so it could be the form 
240                obtained from `get_form` just with the data entered. 
241   
242          :return: new registration element 
243          :returntype: `Register`""" 
244   
245          result = Register() 
246          if self.form: 
247              result.form = form.make_submit() 
248              return result 
249   
250          if "FORM_TYPE" not in form or "jabber:iq:register" not in form["FORM_TYPE"].values: 
251              raise ValueError, "FORM_TYPE is not jabber:iq:register" 
252   
253          for field in legacy_fields: 
254              self.__logger.debug(u"submitted field %r" % (field, )) 
255              value = getattr(self, field) 
256              try: 
257                  form_value = form[field].value 
258              except KeyError: 
259                  if value: 
260                      raise ValueError, "Required field with no value!" 
261                  continue 
262              setattr(result, field, form_value) 
263   
264          return result 
265   
266   
267  # vi: sts=4 et sw=4 
268   
| Home | Trees | Indices | Help | 
 | 
|---|
| Generated by Epydoc 3.0.1 on Sat Jan 17 19:19:53 2009 | http://epydoc.sourceforge.net |