Show
Ignore:
Timestamp:
09/05/08 22:58:17 (18 months ago)
Author:
cmlenz
Message:

Some early and rough support for OpenID 2, minus the XRI/Yadis stuff.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/examples/divan/divan/comments.py

    r199 r200  
    9898            'Host': get_hostname(comment.openid_server) 
    9999        }) 
    100         result = body.strip().split(':', 1) 
    101         if result == ['is_valid', 'true']: 
     100        result = parse_kv_encoding(body.strip()) 
     101        if result['is_valid'] == 'true': 
    102102            log.info('OpenID authentication for %r validated by %r', 
    103103                     comment.openid, comment.openid_server) 
     
    142142            return redirect_to(view.post, *post.path()) 
    143143        if form.validate(request.POST) and 'preview' not in request.POST: 
    144             log.info('Attempting OpenID authentication for %r', 
    145                      form['openid_url']) 
     144            claimed_id = form['openid_url'] 
     145            log.info('Attempting OpenID authentication for %r', claimed_id) 
    146146            try: 
    147                 server, identity = resolve_openid(form['openid_url']) 
     147                provider, local_id, version = resolve_openid(claimed_id) 
    148148            except AuthenticationError, e: 
    149149                form.errors[None] = [e.args[0]] 
    150150            else: 
    151                 log.info('OpenID resolved to %r via %r', identity, server) 
     151                log.info('OpenID resolved to %r via %r', local_id, provider) 
    152152 
    153153                try: 
     
    158158                else: 
    159159                    comment = Comment(post_id=post.id, time=datetime.utcnow(), 
    160                                       openid=form['openid_url'], 
    161                                       openid_server=server, 
    162                                       openid_identity=identity, 
     160                                      openid=claimed_id, 
     161                                      openid_server=provider, 
     162                                      openid_identity=local_id, 
    163163                                      markup=markup, 
    164164                                      **form.data) 
     
    166166 
    167167                    response.set_cookie('author', comment.author) 
    168                     response.set_cookie('openid', comment.openid) 
    169  
    170                     return redirect_to(server, **{ 
     168                    response.set_cookie('openid', claimed_id) 
     169 
     170                    params = { 
    171171                        'openid.mode': 'checkid_setup', 
    172                         'openid.identity': identity, 
    173                         'openid.return_to': abs_url(path_to('authenticate', comment.id)), 
    174                         'openid.trust_root': abs_url(path_to('index')) 
    175                     }) 
     172                        'openid.identity': local_id, 
     173                        'openid.return_to': abs_url(path_to('authenticate', comment.id)) 
     174                    } 
     175                    if version >= 2: 
     176                        params.update({ 
     177                            'openid.ns': 'http://specs.openid.net/auth/2.0', 
     178                            'openid.claimed_id': claimed_id, 
     179                            'openid.identity': local_id, 
     180                            'openid.realm': abs_url(path_to('index')) 
     181                        }) 
     182                    else: 
     183                        params.update({ 
     184                            'openid.trust_root': abs_url(path_to('index')) 
     185                        }) 
     186 
     187                    return redirect_to(provider, **params) 
     188 
    176189        try: 
    177190            preview = to_xhtml(form['content']) 
     
    208221 
    209222 
     223def parse_kv_encoding(string): 
     224    lines = string.splitlines() 
     225    retval = {} 
     226    for line in lines: 
     227        key, value = line.split(':', 1) 
     228        retval[key] = value 
     229    return retval 
     230 
     231 
    210232def resolve_openid(url): 
     233    """Resolve the given OpenID URL and return a tuple of the form 
     234    `(provider_url, identity_url, version)`. 
     235    """ 
    211236    http = Http() 
    212237    resp, body = http.request(url, method='GET', headers={ 
     
    225250 
    226251    soup = BeautifulSoup(body, fromEncoding=params.get('charset')) 
    227     server_tag = soup.findAll('link', rel='openid.server') 
    228     if not server_tag: 
    229         raise AuthenticationError('OpenID HTML resource contains no ' 
    230                                   '"openid.server" link') 
    231     server_url = server_tag[0]['href'] 
    232  
    233     delegate_tag = soup.findAll('link', rel='openid.delegate') 
    234     if not delegate_tag: 
    235         openid_identity = url 
    236     else: 
    237         openid_identity = delegate_tag[0]['href'] 
    238  
    239     return server_url, openid_identity 
     252    provider_tag = soup.findAll('link', rel='openid2.provider') 
     253    if provider_tag: 
     254        version = 2 
     255    else: 
     256        provider_tag = soup.findAll('link', rel='openid.server') 
     257        if not provider_tag: 
     258            raise AuthenticationError('OpenID HTML resource contains no ' 
     259                                      '"openid.server" link') 
     260        version = 1 
     261    provider_url = provider_tag[0]['href'] 
     262 
     263    if version == 2: 
     264        identity_tag = soup.findAll('link', rel='openid2.local_id') 
     265    else: 
     266        identity_tag = soup.findAll('link', rel='openid.delegate') 
     267    if not identity_tag: 
     268        identity_url = url 
     269    else: 
     270        identity_url = identity_tag[0]['href'] 
     271 
     272    return provider_url, identity_url, version