OpenSecurity/install/web.py-0.37/build/lib/web/webopenid.py
author om
Mon, 02 Dec 2013 14:02:05 +0100
changeset 3 65432e6c6042
permissions -rwxr-xr-x
initial deployment and project layout commit
     1 """openid.py: an openid library for web.py
     2 
     3 Notes:
     4 
     5  - This will create a file called .openid_secret_key in the 
     6    current directory with your secret key in it. If someone 
     7    has access to this file they can log in as any user. And 
     8    if the app can't find this file for any reason (e.g. you 
     9    moved the app somewhere else) then each currently logged 
    10    in user will get logged out.
    11 
    12  - State must be maintained through the entire auth process 
    13    -- this means that if you have multiple web.py processes 
    14    serving one set of URLs or if you restart your app often 
    15    then log ins will fail. You have to replace sessions and 
    16    store for things to work.
    17 
    18  - We set cookies starting with "openid_".
    19 
    20 """
    21 
    22 import os
    23 import random
    24 import hmac
    25 import __init__ as web
    26 import openid.consumer.consumer
    27 import openid.store.memstore
    28 
    29 sessions = {}
    30 store = openid.store.memstore.MemoryStore()
    31 
    32 def _secret():
    33     try:
    34         secret = file('.openid_secret_key').read()
    35     except IOError:
    36         # file doesn't exist
    37         secret = os.urandom(20)
    38         file('.openid_secret_key', 'w').write(secret)
    39     return secret
    40 
    41 def _hmac(identity_url):
    42     return hmac.new(_secret(), identity_url).hexdigest()
    43 
    44 def _random_session():
    45     n = random.random()
    46     while n in sessions:
    47         n = random.random()
    48     n = str(n)
    49     return n
    50 
    51 def status():
    52     oid_hash = web.cookies().get('openid_identity_hash', '').split(',', 1)
    53     if len(oid_hash) > 1:
    54         oid_hash, identity_url = oid_hash
    55         if oid_hash == _hmac(identity_url):
    56             return identity_url
    57     return None
    58 
    59 def form(openid_loc):
    60     oid = status()
    61     if oid:
    62         return '''
    63         <form method="post" action="%s">
    64           <img src="http://openid.net/login-bg.gif" alt="OpenID" />
    65           <strong>%s</strong>
    66           <input type="hidden" name="action" value="logout" />
    67           <input type="hidden" name="return_to" value="%s" />
    68           <button type="submit">log out</button>
    69         </form>''' % (openid_loc, oid, web.ctx.fullpath)
    70     else:
    71         return '''
    72         <form method="post" action="%s">
    73           <input type="text" name="openid" value="" 
    74             style="background: url(http://openid.net/login-bg.gif) no-repeat; padding-left: 18px; background-position: 0 50%%;" />
    75           <input type="hidden" name="return_to" value="%s" />
    76           <button type="submit">log in</button>
    77         </form>''' % (openid_loc, web.ctx.fullpath)
    78 
    79 def logout():
    80     web.setcookie('openid_identity_hash', '', expires=-1)
    81 
    82 class host:
    83     def POST(self):
    84         # unlike the usual scheme of things, the POST is actually called
    85         # first here
    86         i = web.input(return_to='/')
    87         if i.get('action') == 'logout':
    88             logout()
    89             return web.redirect(i.return_to)
    90 
    91         i = web.input('openid', return_to='/')
    92 
    93         n = _random_session()
    94         sessions[n] = {'webpy_return_to': i.return_to}
    95         
    96         c = openid.consumer.consumer.Consumer(sessions[n], store)
    97         a = c.begin(i.openid)
    98         f = a.redirectURL(web.ctx.home, web.ctx.home + web.ctx.fullpath)
    99 
   100         web.setcookie('openid_session_id', n)
   101         return web.redirect(f)
   102 
   103     def GET(self):
   104         n = web.cookies('openid_session_id').openid_session_id
   105         web.setcookie('openid_session_id', '', expires=-1)
   106         return_to = sessions[n]['webpy_return_to']
   107 
   108         c = openid.consumer.consumer.Consumer(sessions[n], store)
   109         a = c.complete(web.input(), web.ctx.home + web.ctx.fullpath)
   110 
   111         if a.status.lower() == 'success':
   112             web.setcookie('openid_identity_hash', _hmac(a.identity_url) + ',' + a.identity_url)
   113 
   114         del sessions[n]
   115         return web.redirect(return_to)