From: Drew Fisher <drew@aerofs.com>
Date: Wed, 12 Mar 2014 17:56:07 +0000 (-0700)
Subject: Login/logout.
X-Git-Url: http://git.zarvox.org/shortlog/%7Bdate%7D?a=commitdiff_plain;h=cb4ae29db35ab388ce9241d1a5916c0c990cfa12;p=imoo.git

Login/logout.

Note that there's no user creation flow yet, so you'll have to manually
frob your DB to test this at the moment.
---

diff --git a/imoo/__init__.py b/imoo/__init__.py
index d6f0a4c..7f219c3 100644
--- a/imoo/__init__.py
+++ b/imoo/__init__.py
@@ -39,9 +39,8 @@ def create_app():
 
     # Enable plugins:
     # 1) Flask-Login
-    # Disabled until the views are implemented
-    #login_namager.init_app(app)
-    #login_manager.login_view = '.login_page'
+    login_manager.init_app(app)
+    login_manager.login_view = 'main.login_page'
 
     # 2) Flask-WTF CSRF protection
     csrf.init_app(app)
diff --git a/imoo/api.py b/imoo/api.py
index a0eaf13..50db0f0 100644
--- a/imoo/api.py
+++ b/imoo/api.py
@@ -1,5 +1,6 @@
 from flask import Blueprint
 from flask.ext.restful import Api, Resource, marshal, marshal_with, fields
+from flask.ext import login
 
 blueprint = Blueprint('api', 'api')
 api = Api(blueprint)
diff --git a/imoo/templates/index.html b/imoo/templates/index.html
index c8b2098..aef6376 100644
--- a/imoo/templates/index.html
+++ b/imoo/templates/index.html
@@ -7,5 +7,6 @@
 {% block content %}
 <ul>
     <li><a href="/login">Log in</a></li>
+    <li><a href="/logout">Log out</a></li>
 </ul>
 {% endblock %}
diff --git a/imoo/views.py b/imoo/views.py
index 0707234..2b216e8 100644
--- a/imoo/views.py
+++ b/imoo/views.py
@@ -1,17 +1,50 @@
-from flask import Blueprint, render_template, flash
+from flask import Blueprint, render_template, flash, redirect, url_for
+from flask.ext import login, scrypt
 
 from imoo import db, login_manager
 from . import forms, models
 
 blueprint = Blueprint('main', __name__, template_folder='templates')
 
+@login_manager.user_loader
+def load_user(userid):
+    return models.User.query.get(userid)
+
 @blueprint.route("/")
 def index():
     return render_template('index.html')
 
 @blueprint.route("/login", methods=["GET", "POST"])
-def login():
+def login_page():
     form = forms.LoginForm()
     if form.validate_on_submit():
-        flash(u"login form submitted", "success")
+        user = models.User.query.filter_by(username=form.username.data).first()
+        if not user:
+            # User does not exist.
+            flash(u'Username or password is incorrect', 'error')
+        elif not scrypt.check_password_hash(form.password.data, user.pw_hash, user.pw_salt):
+            # User exists, but wrong password.  Give same behavior as no user
+            # existing, to try to prevent mining of usernames.
+            flash(u'Username or password is incorrect', 'error')
+        else:
+            # Successful login.
+            login_success = login.login_user(user, remember=False)
+            if login_success:
+                pass
+            else:
+                flash(u'Login failed for {} - is that user marked inactive?'.format(user.username), 'error')
+            return redirect(url_for('.test_protected'))
     return render_template('login.html', form=form)
+
+# Ideally, logout would be POST-only but I'm leaving it as a link for easier manual testing
+@blueprint.route("/logout", methods=["GET", "POST"])
+def logout_page():
+    login.logout_user()
+    flash(u"You have logged out successfully", 'success')
+    return redirect(url_for('.index'))
+
+@blueprint.route('/test_protected', methods=["GET"])
+@login.login_required
+def test_protected():
+    flash(u"protected page", 'success')
+    return render_template("index.html")