Martin von Löwis avatar Martin von Löwis committed b02f33e

Add SREG and AX requests to request_authentication.

Comments (0)

Files changed (3)

   parse_qs results are still supported for compatibility.
 * Split test application into separate file
 * Drop BeautifulSoup dependency, drop setuptools usage
+* Allow applications to request specific SREG and AX values
 1.2 (2010-07-02):
   preserved atleast until authentication is completed, and can be
   reused at most until the 'expires_in' amount of seconds has passed.
-.. function:: request_authentication(services, url, assoc_handle, return_to, claimed=None, op_local=None, realm=None) -> url
+.. function:: request_authentication(services, url, assoc_handle, return_to, claimed=None, op_local=None, realm=None, sreg=(('nickname', 'email'), ()), ax = ((, ax.first, ax.last), ())) -> url
   Create an authentication request; return the URL that the user
   should be redirected to. services and url are the same parameters as
   work, the return_to URL must match the realm (see 9.2. of the OpenID
   spec how matching is defined).
+  sreg is a pair of required and optional SREG (simple registration)
+  fields. Applications should declare those fields required that they
+  absolutely need to complete user registration; i.e. failure to provide
+  some of the required values will cause user interaction to let the
+  user fill in the missing values.
+  ax is a pair of required and "if available" AX (attribute exchange)
+  attribute types. The provider should use these lists as a guidance
+  what attributes to send back; the specification allows it to
+  interpret this request in any way it pleases. Values must be URL,
+  the AX object provides a shortcut notation for common attributes.
 .. function:: authenticate(session, response) -> None
   Process an authentication response.  session must be the established
 * AX attributes, as processed by
   get_ax. is a registry for attribute types.
+AX Mapping
+To simplify usage of AX, shortcut names of the form openid2rp.AX.NAME
+are provided. These can be used for lookup in the get_ax result, and
+for specifying required and "if available" attributes for
+====== ======================================
+Name   URL
+====== ======================================
+====== ======================================
 Indices and tables
         data['mac_key'] = base64.b64encode(string_xor(enc_mac_key, shared_secret))
     return data
+class _AX:
+    def __init__(self):
+        self.__dict__['_reverse'] = {}
+    def __setattr__(self, name, value):
+        self.__dict__[name] = value
+        self._reverse[value] = name
+    def lookup(self, value):
+        try:
+            return self._reverse[value]
+        except KeyError:
+            return 'a%d' % (hash(value) % 1000000000)
+AX = _AX() = ''
+AX.first = ""
+AX.last = ""
 def request_authentication(services, url, assoc_handle, return_to,
-                           claimed=None, op_local=None, realm=None):
+                           claimed=None, op_local=None, realm=None,
+                           sreg = (('nickname', 'email'), ()),
+                           ax = ((, AX.first, AX.last), ())):
     '''Request authentication (OpenID section 9).
     services is the list of discovered service types,
     url the OP service URL, assoc_handle the established session
-        'openid.ns.sreg':"",
+    sreg_req, sreg_opt = sreg
+    sreg11 = {}
+    if sreg_req or sreg_opt:
+        data['openid.ns.sreg'] = ""
+        if sreg_req:
+            data['openid.sreg.required'] = sreg11['openid.sreg11.required'] = ','.join(sreg_req)
+        if sreg_opt:
+            data['openid.sreg.optional'] =  sreg11['openid.sreg11.optional'] =','.join(sreg_opt)
     if is_compat_1x(services):
         del data['openid.ns']
         del data['openid.claimed_id']
         del data['openid.realm']
         data['openid.trust_root'] = return_to
-    if "" in services:
+    ax_req, ax_opt = ax
+    if "" in services and (ax_req or ax_opt):
-            '':'email,first,last',
-            '':'',
-            '':"",
-            '':"",
-    if "" in services:
+        for uri in ax_req + ax_opt:
+            data[''+AX.lookup(uri)] = uri
+        if ax_req:
+            data[''] = ','.join(AX.lookup(uri) for uri in ax_req)
+        if ax_opt:
+            data[''] = ','.join(AX.lookup(uri) for uri in ax_req)
+    if "" in services and sreg11:
-            'openid.sreg11.required':'nickname,email'
+        data.update(sreg11)
     if '?' in url:
         return url+'&'+urllib.urlencode(data)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.