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 testapp.py
 * 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.email, 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. http://www.axschema.org/types/ 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
+request_authentication.
+
+====== ======================================
+Name   URL
+====== ======================================
+email  http://axschema.org/contact/email
+first  http://axschema.org/namePerson/first
+last   http://axschema.org/namePerson/last
+====== ======================================
 
 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.email = 'http://axschema.org/contact/email'
+AX.first = "http://axschema.org/namePerson/first"
+AX.last = "http://axschema.org/namePerson/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.email, 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.claimed_id':claimed,
         'openid.identity':op_local,
         'openid.realm':realm,
-        'openid.ns.sreg':"http://openid.net/sreg/1.0",
         'openid.sreg.required':'nickname,email',
         }
+    sreg_req, sreg_opt = sreg
+    sreg11 = {}
+    if sreg_req or sreg_opt:
+        data['openid.ns.sreg'] = "http://openid.net/sreg/1.0"
+        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 "http://openid.net/srv/ax/1.0" in services:
+    ax_req, ax_opt = ax
+    if "http://openid.net/srv/ax/1.0" in services and (ax_req or ax_opt):
         data.update({
             'openid.ns.ax':"http://openid.net/srv/ax/1.0",
             'openid.ax.mode':'fetch_request',
-            'openid.ax.required':'email,first,last',
-            'openid.ax.type.email':'http://axschema.org/contact/email',
-            'openid.ax.type.first':"http://axschema.org/namePerson/first",
-            'openid.ax.type.last':"http://axschema.org/namePerson/last",
             })
-    if "http://openid.net/extensions/sreg/1.1" in services:
+        for uri in ax_req + ax_opt:
+            data['openid.ax.'+AX.lookup(uri)] = uri
+        if ax_req:
+            data['openid.ax.required'] = ','.join(AX.lookup(uri) for uri in ax_req)
+        if ax_opt:
+            data['openid.ax.optional'] = ','.join(AX.lookup(uri) for uri in ax_req)
+    if "http://openid.net/extensions/sreg/1.1" in services and sreg11:
         data.update({
             'openid.ns.sreg11':"http://openid.net/extensions/sreg/1.1",
-            'openid.sreg11.required':'nickname,email'
             })
+        data.update(sreg11)
     if '?' in url:
         return url+'&'+urllib.urlencode(data)
     else:
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 ProjectModifiedEvent.java.
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.