From 5ae52414850aa57856f65f9f5584bfa21ea2fef6 Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Sun, 16 Dec 2012 00:30:41 -0800 Subject: [PATCH] user authentication --- app/__init__.py | 8 +++++++ app/models.py | 14 +++++++++++- app/templates/base.html | 7 +++++- app/views.py | 49 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 71 insertions(+), 7 deletions(-) diff --git a/app/__init__.py b/app/__init__.py index 67ffa87..c7a1b90 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,9 +1,17 @@ +import os from flask import Flask from flask.ext.sqlalchemy import SQLAlchemy +from flask.ext.login import LoginManager +from flask.ext.openid import OpenID +from config import basedir app = Flask(__name__) app.config.from_object('config') db = SQLAlchemy(app) +lm = LoginManager() +lm.setup_app(app) +lm.login_view = 'login' +oid = OpenID(app, os.path.join(basedir, 'tmp')) from app import views, models diff --git a/app/models.py b/app/models.py index 4bf9b23..bcf2b7d 100644 --- a/app/models.py +++ b/app/models.py @@ -5,11 +5,23 @@ ROLE_ADMIN = 1 class User(db.Model): id = db.Column(db.Integer, primary_key = True) - nickname = db.Column(db.String(64), index = True, unique = True) + nickname = db.Column(db.String(64), unique = True) email = db.Column(db.String(120), index = True, unique = True) role = db.Column(db.SmallInteger, default = ROLE_USER) posts = db.relationship('Post', backref = 'author', lazy = 'dynamic') + def is_authenticated(self): + return True + + def is_active(self): + return True + + def is_anonymous(self): + return False + + def get_id(self): + return unicode(self.id) + def __repr__(self): return '' % (self.nickname) diff --git a/app/templates/base.html b/app/templates/base.html index 0a3d1e9..1208920 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -7,7 +7,12 @@ {% endif %} -
Microblog: Home
+
Microblog: + Home + {% if g.user.is_authenticated() %} + | Logout + {% endif %} +

{% with messages = get_flashed_messages() %} {% if messages %} diff --git a/app/views.py b/app/views.py index b6cb21f..84e9943 100644 --- a/app/views.py +++ b/app/views.py @@ -1,11 +1,22 @@ -from flask import render_template, flash, redirect -from app import app +from flask import render_template, flash, redirect, session, url_for, request, g +from flask.ext.login import login_user, logout_user, current_user, login_required +from app import app, db, lm, oid from forms import LoginForm +from models import User, ROLE_USER, ROLE_ADMIN +@lm.user_loader +def load_user(id): + return User.query.get(int(id)) + +@app.before_request +def before_request(): + g.user = current_user + @app.route('/') @app.route('/index') +@login_required def index(): - user = { 'nickname': 'Miguel' } + user = g.user posts = [ { 'author': { 'nickname': 'John' }, @@ -22,12 +33,40 @@ def index(): posts = posts) @app.route('/login', methods = ['GET', 'POST']) +@oid.loginhandler def login(): + if g.user is not None and g.user.is_authenticated(): + return redirect(url_for('index')) form = LoginForm() if form.validate_on_submit(): - flash('Login requested for OpenID="' + form.openid.data + '", remember_me=' + str(form.remember_me.data)) - return redirect('/index') + session['remember_me'] = form.remember_me.data + return oid.try_login(form.openid.data, ask_for = ['nickname', 'email']) return render_template('login.html', title = 'Sign In', form = form, providers = app.config['OPENID_PROVIDERS']) + +@oid.after_login +def after_login(resp): + if resp.email is None or resp.email == "": + flash('Invalid login. Please try again.') + redirect(url_for('login')) + user = User.query.filter_by(email = resp.email).first() + if user is None: + nickname = resp.nickname + if nickname is None or nickname == "": + nickname = resp.email.split('@')[0] + user = User(nickname = nickname, email = resp.email, role = ROLE_USER) + db.session.add(user) + db.session.commit() + remember_me = False + if 'remember_me' in session: + remember_me = session['remember_me'] + session.pop('remember_me', None) + login_user(user, remember = remember_me) + return redirect(request.args.get('next') or url_for('index')) + +@app.route('/logout') +def logout(): + logout_user() + return redirect(url_for('index')) \ No newline at end of file