import os
basedir = os.path.abspath(os.path.dirname(__file__))
+
+# SQLAlchemy connection string
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'state', 'database.db')
+
+# CSRF protection: generate a CSRF secret key if none exists
+CSRF_ENABLED=True
+csrf_keyfile = os.path.join(basedir, 'state', 'csrf_secret')
+if not os.path.exists(csrf_keyfile):
+ with open("/dev/urandom") as rng:
+ key = rng.read(64)
+ with open(csrf_keyfile, "w") as f:
+ f.write(key)
+
+with open(csrf_keyfile) as f:
+ SECRET_KEY = f.read()
from wtforms import TextField, PasswordField, IntegerField, DateField, SelectField, TextAreaField
from wtforms.validators import ValidationError, InputRequired, Email, Length, Optional
-
+class LoginForm(Form):
+ username = TextField("Username", validators=[InputRequired()])
+ password = PasswordField("Password", validators=[InputRequired()])
--- /dev/null
+/* Yeah, this isn't a proper stylesheet. Frontend devs, replace this at will */
+
+header > #messages > ul {
+ background-color: #dedede;
+}
+header > #messages > ul > li {
+ list-style: none;
+}
--- /dev/null
+{% macro render_field(field) %}
+<div class="form-label">{{ field.label }}</div>
+<div class="form-field">{{ field(**kwargs)|safe }}</div>
+{% if field.errors %}
+ <ul class=errors>
+ {% for error in field.errors %}
+ <li><span style="color: red;">{{ error }}</span></li>
+ {% endfor %}
+ </ul>
+{% endif %}
+{% endmacro %}
+
+{% macro submit_button(button_text) %}
+<input type="submit" value="{{ button_text }}">
+{% endmacro %}
--- /dev/null
+<!doctype html>
+<html lang="en-US">
+ <head>
+ <title>{% block title %}IMOO{% endblock %}</title>
+ <link href="{{ url_for('static', filename='style.css') }}" rel="stylesheet" />
+ {% block head %}{% endblock %}
+ </head>
+ <body>
+ {% block layout %}{% endblock %}
+ </body>
+</html>
--- /dev/null
+{% extends 'main.html' %}
+
+{% block header %}
+<h1>It works.</h1>
+{% endblock header %}
+
+{% block content %}
+<ul>
+ <li><a href="/login">Log in</a></li>
+</ul>
+{% endblock %}
--- /dev/null
+{% extends 'main.html' %}
+{% from '_formhelpers.html' import render_field, submit_button %}
+
+{% block content %}
+<h1>LOG IN FIRST, SCRUB</h1>
+
+<form action="" method="post">
+ {{ form.hidden_tag() }}
+ {{ render_field(form.username) }}
+ {{ render_field(form.password) }}
+ {{ submit_button("Login") }}
+</form>
+{% endblock %}
--- /dev/null
+{% extends 'base.html' %}
+
+{% block layout %}
+ <header>
+ {% with messages = get_flashed_messages(with_categories=True) %}
+ {% if messages %}
+ <div id="messages">
+ <ul>
+ {% for category, message in messages %}
+ <li class="{{ category }}">{{ message }}</li>
+ {% endfor %}
+ </ul>
+ </div>
+ {% endif %}
+ {% endwith %}
+ {% block header %}
+ {% endblock %}
+ </header>
+ <main>
+ {% block content %}{% endblock %}
+ </main>
+ <footer>
+ {% block footer %}{% endblock %}
+ </footer>
+{% endblock %}
-from flask import Blueprint
+from flask import Blueprint, render_template, flash
from imoo import db, login_manager
from . import forms, models
blueprint = Blueprint('main', __name__, template_folder='templates')
@blueprint.route("/")
-def test():
- return "<!doctype html><html><body><h1>HI THERE</h1></body></html>"
+def index():
+ return render_template('index.html')
+
+@blueprint.route("/login", methods=["GET", "POST"])
+def login():
+ form = forms.LoginForm()
+ if form.validate_on_submit():
+ flash(u"login form submitted", "success")
+ return render_template('login.html', form=form)