Package web :: Package web :: Module webopenid
[hide private]
[frames] | no frames]

Source Code for Module web.web.webopenid

  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)
116