Anonymous avatar Anonymous committed 685e59b

add support for ax extensions so now google openid and yahoo openid
work.

Comments (0)

Files changed (2)

django_authopenid/utils/__init__.py

         self.issued = issued
         self.attrs = attrs or {}
         self.sreg = sreg_ or {}
-        self.ax = ax_
+        self.ax = ax_ or {}
         self.is_iname = (xri.identifierScheme(openid_) == 'XRI')
     
     def __repr__(self):
     def __str__(self):
         return self.openid
     
-SUPPORTED_EXTENSIONS = {
-    "http://openid.net/srv/ax/1.0": ax,
-    'http://openid.net/sreg/1.0': sreg,
-    'http://openid.net/extensions/sreg/1.1': sreg
-}   
-
 def discover_extensions(openid_url):
     service = discover(openid_url)
-    found = []
+    use_ax = False
+    use_sreg = False
     for endpoint in service[1]:
-        found = filter(endpoint.usesExtension, SUPPORTED_EXTENSIONS.keys())
-    return found
+        if not use_sreg:
+            use_sreg = sreg.supportsSReg(endpoint)
+        if not use_ax:
+            use_ax = endpoint.usesExtension("http://openid.net/srv/ax/1.0")
+        if use_ax and use_sreg: break
+    return use_ax, use_sreg
+
 
 DEFAULT_NEXT = getattr(settings, 'OPENID_REDIRECT_NEXT', '/')
 def clean_next(next):
     issued = int(time.time())
     sreg_resp = sreg.SRegResponse.fromSuccessResponse(openid_response) \
             or []
-    
+    ax_resp = ax.FetchResponse.fromSuccessResponse(openid_response)
+    ax_args = ax_resp.getExtensionArgs()
+    ax_resp.parseExtensionArgs(ax_args)
+
     return OpenID(
         openid_response.identity_url, issued, openid_response.signed_fields, 
-         dict(sreg_resp)
+        dict(sreg_resp), ax_resp.data
     )
     
 def get_url_host(request):

django_authopenid/views.py

 from openid.consumer.consumer import Consumer, \
     SUCCESS, CANCEL, FAILURE, SETUP_NEEDED
 from openid.consumer.discover import DiscoveryFailure
-from openid.extensions import sreg
+from openid.extensions import sreg, ax
 # needed for some linux distributions like debian
 try:
     from openid.yadis import xri
 def ask_openid(request, openid_url, redirect_to, on_failure=None):
     """ basic function to ask openid and return response """
     on_failure = on_failure or signin_failure
+    sreg_req = None
+    sreg_ax = None
     
     trust_root = getattr(
         settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
         msg = _("The OpenID %s was invalid" % openid_url)
         return on_failure(request, msg)
     
-    # set sreg extension
-    # we always ask for nickname and email
-    sreg_fields = getattr(settings, 'OPENID_SREG', {})
-    sreg_fields.update({ "optional": ['nickname', 'email'] })
-    auth_request.addExtension(sreg.SRegRequest(**sreg_fields))
+    # get capabilities
+    use_ax, use_sreg = discover_extensions(openid_url)
+    if use_sreg:
+        # set sreg extension
+        # we always ask for nickname and email
+        sreg_attrs = getattr(settings, 'OPENID_SREG', {})
+        sreg_attrs.update({ "optional": ['nickname', 'email'] })
+        sreg_req = sreg.SRegRequest(**sreg_attrs)
+    if use_ax:
+        # set ax extension
+        # we always ask for nickname and email
+        ax_req = ax.FetchRequest()
+        ax_req.add(ax.AttrInfo('http://schema.openid.net/contact/email', 
+                                alias='email', required=True))
+        ax_req.add(ax.AttrInfo('http://schema.openid.net/namePerson/friendly', 
+                                alias='nickname', required=True))
+                      
+        # add custom ax attrs          
+        ax_attrs = getattr(settings, 'OPENID_AX', [])
+        for attr in ax_attrs:
+            if len(attr) == 2:
+                ax_req.add(ax.AttrInfo(attr[0], required=alias[1]))
+            else:
+                ax_req.add(ax.AttrInfo(attr[0]))
+       
+    if sreg_req is not None:
+        auth_request.addExtension(sreg_req)
+    if ax_req is not None:
+        auth_request.addExtension(ax_req)
     
     redirect_url = auth_request.redirectURL(trust_root, redirect_to)
     return HttpResponseRedirect(redirect_url)
     params = dict((k,smart_unicode(v)) for k, v in request.GET.items())
     openid_response = consumer.complete(params, return_to)
             
-    
     if openid_response.status == SUCCESS:
         return on_success(request, openid_response.identity_url,
                 openid_response, **kwargs)
                                 urllib.urlencode({ 
                                 redirect_field_name: redirect_to })))
 
-    nickname = openid_.sreg.get('nickname', '')
-    email = openid_.sreg.get('email', '')
+    nickname = ''
+    email = ''
+    if openid_.sreg:
+        nickname = openid_.sreg.get('nickname', '')
+        email = openid_.sreg.get('email', '')
+    if openid_.ax and not nickname or not email:
+        if openid_.ax.get('http://schema.openid.net/namePerson/friendly', False):
+            nickname = openid_.ax.get('http://schema.openid.net/namePerson/friendly')[0]
+        if openid_.ax.get('http://schema.openid.net/contact/email', False):
+            email = openid_.ax.get('http://schema.openid.net/contact/email')[0]
+        
     
     form1 = register_form(initial={
         'username': nickname,
         'username': nickname,
     })
     
-    print openid_.sreg
     if request.POST:
         user_ = None
         if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
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.