OpenSecurity/install/web.py-0.37/web/webopenid.py
changeset 3 65432e6c6042
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/OpenSecurity/install/web.py-0.37/web/webopenid.py	Mon Dec 02 14:02:05 2013 +0100
     1.3 @@ -0,0 +1,115 @@
     1.4 +"""openid.py: an openid library for web.py
     1.5 +
     1.6 +Notes:
     1.7 +
     1.8 + - This will create a file called .openid_secret_key in the 
     1.9 +   current directory with your secret key in it. If someone 
    1.10 +   has access to this file they can log in as any user. And 
    1.11 +   if the app can't find this file for any reason (e.g. you 
    1.12 +   moved the app somewhere else) then each currently logged 
    1.13 +   in user will get logged out.
    1.14 +
    1.15 + - State must be maintained through the entire auth process 
    1.16 +   -- this means that if you have multiple web.py processes 
    1.17 +   serving one set of URLs or if you restart your app often 
    1.18 +   then log ins will fail. You have to replace sessions and 
    1.19 +   store for things to work.
    1.20 +
    1.21 + - We set cookies starting with "openid_".
    1.22 +
    1.23 +"""
    1.24 +
    1.25 +import os
    1.26 +import random
    1.27 +import hmac
    1.28 +import __init__ as web
    1.29 +import openid.consumer.consumer
    1.30 +import openid.store.memstore
    1.31 +
    1.32 +sessions = {}
    1.33 +store = openid.store.memstore.MemoryStore()
    1.34 +
    1.35 +def _secret():
    1.36 +    try:
    1.37 +        secret = file('.openid_secret_key').read()
    1.38 +    except IOError:
    1.39 +        # file doesn't exist
    1.40 +        secret = os.urandom(20)
    1.41 +        file('.openid_secret_key', 'w').write(secret)
    1.42 +    return secret
    1.43 +
    1.44 +def _hmac(identity_url):
    1.45 +    return hmac.new(_secret(), identity_url).hexdigest()
    1.46 +
    1.47 +def _random_session():
    1.48 +    n = random.random()
    1.49 +    while n in sessions:
    1.50 +        n = random.random()
    1.51 +    n = str(n)
    1.52 +    return n
    1.53 +
    1.54 +def status():
    1.55 +    oid_hash = web.cookies().get('openid_identity_hash', '').split(',', 1)
    1.56 +    if len(oid_hash) > 1:
    1.57 +        oid_hash, identity_url = oid_hash
    1.58 +        if oid_hash == _hmac(identity_url):
    1.59 +            return identity_url
    1.60 +    return None
    1.61 +
    1.62 +def form(openid_loc):
    1.63 +    oid = status()
    1.64 +    if oid:
    1.65 +        return '''
    1.66 +        <form method="post" action="%s">
    1.67 +          <img src="http://openid.net/login-bg.gif" alt="OpenID" />
    1.68 +          <strong>%s</strong>
    1.69 +          <input type="hidden" name="action" value="logout" />
    1.70 +          <input type="hidden" name="return_to" value="%s" />
    1.71 +          <button type="submit">log out</button>
    1.72 +        </form>''' % (openid_loc, oid, web.ctx.fullpath)
    1.73 +    else:
    1.74 +        return '''
    1.75 +        <form method="post" action="%s">
    1.76 +          <input type="text" name="openid" value="" 
    1.77 +            style="background: url(http://openid.net/login-bg.gif) no-repeat; padding-left: 18px; background-position: 0 50%%;" />
    1.78 +          <input type="hidden" name="return_to" value="%s" />
    1.79 +          <button type="submit">log in</button>
    1.80 +        </form>''' % (openid_loc, web.ctx.fullpath)
    1.81 +
    1.82 +def logout():
    1.83 +    web.setcookie('openid_identity_hash', '', expires=-1)
    1.84 +
    1.85 +class host:
    1.86 +    def POST(self):
    1.87 +        # unlike the usual scheme of things, the POST is actually called
    1.88 +        # first here
    1.89 +        i = web.input(return_to='/')
    1.90 +        if i.get('action') == 'logout':
    1.91 +            logout()
    1.92 +            return web.redirect(i.return_to)
    1.93 +
    1.94 +        i = web.input('openid', return_to='/')
    1.95 +
    1.96 +        n = _random_session()
    1.97 +        sessions[n] = {'webpy_return_to': i.return_to}
    1.98 +        
    1.99 +        c = openid.consumer.consumer.Consumer(sessions[n], store)
   1.100 +        a = c.begin(i.openid)
   1.101 +        f = a.redirectURL(web.ctx.home, web.ctx.home + web.ctx.fullpath)
   1.102 +
   1.103 +        web.setcookie('openid_session_id', n)
   1.104 +        return web.redirect(f)
   1.105 +
   1.106 +    def GET(self):
   1.107 +        n = web.cookies('openid_session_id').openid_session_id
   1.108 +        web.setcookie('openid_session_id', '', expires=-1)
   1.109 +        return_to = sessions[n]['webpy_return_to']
   1.110 +
   1.111 +        c = openid.consumer.consumer.Consumer(sessions[n], store)
   1.112 +        a = c.complete(web.input(), web.ctx.home + web.ctx.fullpath)
   1.113 +
   1.114 +        if a.status.lower() == 'success':
   1.115 +            web.setcookie('openid_identity_hash', _hmac(a.identity_url) + ',' + a.identity_url)
   1.116 +
   1.117 +        del sessions[n]
   1.118 +        return web.redirect(return_to)