Added snippet database to the website.

This commit is contained in:
Armin Ronacher 2010-05-03 11:20:52 +02:00
parent a81cf3a67c
commit 0ab7a9cb67
22 changed files with 825 additions and 118 deletions

View file

@ -0,0 +1,134 @@
from __future__ import with_statement
from time import time
from hashlib import sha1
from contextlib import closing
from openid.association import Association
from openid.store.interface import OpenIDStore
from openid.consumer.consumer import Consumer, SUCCESS, CANCEL
from openid.consumer import discover
from openid.store import nonce
from sqlalchemy.orm import scoped_session
from sqlalchemy.exceptions import SQLError
from flask import request, redirect, abort, url_for, flash, session
from flask_website.database import User, db_session, OpenIDAssociation, \
OpenIDUserNonce
class WebsiteOpenIDStore(OpenIDStore):
"""Implements the open store for the website using the database."""
def storeAssociation(self, server_url, association):
assoc = OpenIDAssociation(
server_url=server_url,
handle=association.handle,
secret=association.secret.encode('base64'),
issued=association.issued,
lifetime=association.lifetime,
assoc_type=association.assoc_type
)
db_session.add(assoc)
def getAssociation(self, server_url, handle=None):
q = OpenIDAssociation.query.filter_by(server_url=server_url)
if handle is not None:
q = q.filter_by(handle=handle)
result_assoc = None
for item in q.all():
assoc = Association(item.handle, item.secret.decode('base64'),
item.issued, item.lifetime, item.assoc_type)
if assoc.getExpiresIn() <= 0:
self.removeAssociation(server_url, assoc.handle)
else:
result_assoc = assoc
return result_assoc
def removeAssociation(self, server_url, handle):
return OpenIDAssociation.filter(
(OpenIDAssociation.server_url == server_url) &
(OpenIDAssociation.handle == handle)
).delete()
def useNonce(self, server_url, timestamp, salt):
if abs(timestamp - time()) > nonce.SKEW:
return False
rv = OpenIDUserNonce.query.filter(
(OpenIDUserNonce.server_url == server_url) &
(OpenIDUserNonce.timestamp == timestamp) &
(OpenIDUserNonce.salt == salt)
).first()
if rv is not None:
return False
rv = OpenIDUserNonce(server_url=server_url, timestamp=timestamp,
salt=salt)
db_session.add(rv)
return True
def cleanupNonces(self):
return OpenIDUserNonce.filter(
OpenIDUserNonce.timestamp <= int(time() - nonce.SKEW)
).delete()
def cleanupAssociations(self):
return OpenIDAssociation.filter(
OpenIDAssociation.lifetime < int(time())
).delete()
def getAuthKey(self):
return sha1(config.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
def isDump(self):
return False
def redirect_back():
return redirect(request.values.get('next') or url_for('general.index'))
def check_return_from_provider():
if request.args.get('openid_complete') != u'yes':
return
try:
consumer = Consumer(session, WebsiteOpenIDStore())
openid_response = consumer.complete(request.args.to_dict(),
url_for('general.login',
_external=True))
if openid_response.status == SUCCESS:
return create_or_login(openid_response.identity_url)
elif openid_response.status == CANCEL:
flash(u'Error: The request was cancelled')
return redirect(url_for('general.login'))
flash(u'Error: OpenID authentication error')
return redirect(url_for('general.login'))
finally:
db_session.commit()
def create_or_login(identity_url):
session['openid'] = identity_url
user = User.query.filter_by(openid=identity_url).first()
if user is None:
next_url = request.values.get('next')
return redirect(url_for('general.first_login', next=next_url))
flash(u'Successfully logged in')
return redirect_back()
def login(identity_url):
try:
try:
consumer = Consumer(session, WebsiteOpenIDStore())
auth_request = consumer.begin(identity_url)
except discover.DiscoveryFailure:
flash(u'Error: The OpenID was invalid')
return redirect(url_for('general.login'))
trust_root = request.host_url
next_url = request.values.get('next') or url_for('general.index')
redirect_to = url_for('general.login', openid_complete='yes',
next=next_url, _external=True)
return redirect(auth_request.redirectURL(trust_root, redirect_to))
finally:
db_session.commit()