diff --git a/flask_website/__init__.py b/flask_website/__init__.py index 8ba8a261..8f84970e 100644 --- a/flask_website/__init__.py +++ b/flask_website/__init__.py @@ -1,4 +1,5 @@ from flask import Flask, session, g, render_template +from flaskext.openid import OpenID import websiteconfig as config @@ -6,6 +7,9 @@ app = Flask(__name__) app.debug = config.DEBUG app.secret_key = config.SECRET_KEY +from flask_website.openid_auth import DatabaseOpenIDStore +oid = OpenID(store_factory=DatabaseOpenIDStore) + @app.errorhandler(404) def not_found(error): return render_template('404.html'), 404 diff --git a/flask_website/database.py b/flask_website/database.py index 703417f8..da362879 100644 --- a/flask_website/database.py +++ b/flask_website/database.py @@ -32,6 +32,10 @@ class User(Model): self.name = name self.openid = openid + @property + def is_admin(self): + return self.openid in config.ADMINS + def __eq__(self, other): return type(self) is type(other) and self.id == other.id diff --git a/flask_website/openid_auth.py b/flask_website/openid_auth.py index c16693e9..534ef950 100644 --- a/flask_website/openid_auth.py +++ b/flask_website/openid_auth.py @@ -1,23 +1,14 @@ from time import time -from hashlib import sha1 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 -# python-openid is a really stupid library in that regard, we have -# to disable logging by monkey patching -from openid import oidutil -oidutil.log = lambda *a, **kw: None - -from flask import request, redirect, abort, url_for, flash, session from flask_website.database import User, db_session, OpenIDAssociation, \ OpenIDUserNonce -class WebsiteOpenIDStore(OpenIDStore): +class DatabaseOpenIDStore(OpenIDStore): """Implements the open store for the website using the database.""" def storeAssociation(self, server_url, association): @@ -30,6 +21,7 @@ class WebsiteOpenIDStore(OpenIDStore): assoc_type=association.assoc_type ) db_session.add(assoc) + db_session.commit() def getAssociation(self, server_url, handle=None): q = OpenIDAssociation.query.filter_by(server_url=server_url) @@ -46,10 +38,13 @@ class WebsiteOpenIDStore(OpenIDStore): return result_assoc def removeAssociation(self, server_url, handle): - return OpenIDAssociation.query.filter( - (OpenIDAssociation.server_url == server_url) & - (OpenIDAssociation.handle == handle) - ).delete() + try: + return OpenIDAssociation.query.filter( + (OpenIDAssociation.server_url == server_url) & + (OpenIDAssociation.handle == handle) + ).delete() + finally: + db_session.commit() def useNonce(self, server_url, timestamp, salt): if abs(timestamp - time()) > nonce.SKEW: @@ -64,64 +59,21 @@ class WebsiteOpenIDStore(OpenIDStore): rv = OpenIDUserNonce(server_url=server_url, timestamp=timestamp, salt=salt) db_session.add(rv) + db_session.commit() return True def cleanupNonces(self): - return OpenIDUserNonce.query.filter( - OpenIDUserNonce.timestamp <= int(time() - nonce.SKEW) - ).delete() + try: + return OpenIDUserNonce.query.filter( + OpenIDUserNonce.timestamp <= int(time() - nonce.SKEW) + ).delete() + finally: + db_session.commit() def cleanupAssociations(self): - return OpenIDAssociation.query.filter( - OpenIDAssociation.lifetime < int(time()) - ).delete() - - -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() + return OpenIDAssociation.query.filter( + OpenIDAssociation.lifetime < int(time()) + ).delete() + finally: + db_session.commit() diff --git a/flask_website/static/style.css b/flask_website/static/style.css index 22929486..7c346404 100644 --- a/flask_website/static/style.css +++ b/flask_website/static/style.css @@ -25,6 +25,14 @@ blockquote { margin: 0; font-style: italic; color: #444; } margin: 5px 0 0 0; font-size: 0.9em; } .message { background: #DEEBF3; color: #004B6B; padding: 5px 30px; margin: 10px -30px; } +.actions { margin-top: 0; } +table { border: 1px solid black; border-collapse: collapse; + margin: 15px 0; } +td, th { border: 1px solid black; padding: 4px 10px; + text-align: left; } +th { background: #eee; font-weight: normal; } + +td input { border: none; padding: 0; } /* forms */ input, textarea, select { border: 1px solid black; padding: 2px; background: white; diff --git a/flask_website/templates/general/first_login.html b/flask_website/templates/general/first_login.html index ff42cbfa..69452e58 100644 --- a/flask_website/templates/general/first_login.html +++ b/flask_website/templates/general/first_login.html @@ -18,9 +18,10 @@ site. Choose wisely because you cannot change this value later:
Name: -
+

+ diff --git a/flask_website/templates/general/login.html b/flask_website/templates/general/login.html index 7b34f771..3ada0f0f 100644 --- a/flask_website/templates/general/login.html +++ b/flask_website/templates/general/login.html @@ -16,7 +16,7 @@

OpenID URL: - + {% endblock %} diff --git a/flask_website/templates/snippets/delete_category.html b/flask_website/templates/snippets/delete_category.html new file mode 100644 index 00000000..0e2a56d1 --- /dev/null +++ b/flask_website/templates/snippets/delete_category.html @@ -0,0 +1,20 @@ +{% extends "snippets/layout.html" %} +{% block title %}Snippets Archive{% endblock %} +{% block body %} +

Delete Category “{{ category.name }}”

+

+ Do you want to delete this category? And if yes, what should + happen with the snippets in the category? +

+

+ +

+ + +

+{% endblock %} diff --git a/flask_website/templates/snippets/index.html b/flask_website/templates/snippets/index.html index 0335462d..a0658678 100644 --- a/flask_website/templates/snippets/index.html +++ b/flask_website/templates/snippets/index.html @@ -17,13 +17,17 @@ {% endif %}

Want to share something? Then add a - new snippet. + new snippet.

Snippets by Category

+ {% if g.user.is_admin %} +

+ manage categories + {% endif %} {% if recent %}

Recently Added