| Home | Trees | Indices | Help |
|
|---|
|
|
1 #
2 # (C) Copyright 2005-2010 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 Mon Apr 5 12:26:24 2010 | http://epydoc.sourceforge.net |