server.py 6.08 KB
Newer Older
1 2
#!/usr/bin/env python3

3
from flask import Flask, g, current_app, request, session, flash, redirect, url_for, abort, render_template, Response
4 5
from flask.ext.login import login_user, logout_user, login_required, current_user
from flask.ext.principal import Principal, Identity, AnonymousIdentity, identity_changed, identity_loaded, UserNeed, RoleNeed
Robin Sonnabend's avatar
Robin Sonnabend committed
6
from flask.ext.script import Manager, prompt, prompt_pass
7
from flask.ext.migrate import Migrate, MigrateCommand
8 9 10
from passlib.hash import pbkdf2_sha256

import config
11 12
from shared import db, login_manager
from utils import render_layout
YSelf Tool's avatar
YSelf Tool committed
13
from models.forms import LoginForm, NewUserForm
Robin Sonnabend's avatar
Robin Sonnabend committed
14
from models.database import User, Statement, Speaker, Topic
15 16 17 18

app = Flask(__name__)
app.config.from_object(config)
db.init_app(app)
19 20 21
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
22 23 24 25 26 27
login_manager.init_app(app)
login_manager.login_view = "login"
login_manager.login_message_category = "alert-error"

Principal(app)

YSelf Tool's avatar
YSelf Tool committed
28
from modules import admin, speech
29 30

app.register_blueprint(admin.admin, url_prefix="/admin")
YSelf Tool's avatar
YSelf Tool committed
31
app.register_blueprint(speech.speech, url_prefix="/speech")
32

Robin Sonnabend's avatar
Robin Sonnabend committed
33 34 35 36 37 38 39 40 41 42 43
@manager.command
def addadmin():
    """Add a new administrative user to the system"""
    print("Adding new administrative user:")
    admin_real_name = prompt("Real name")
    admin_login = prompt("Username")
    admin_pass = prompt_pass("Password")
    if admin_real_name is not None and admin_login is not None and admin_pass is not None:
        admin_hashed_pw = pbkdf2_sha256.encrypt(admin_pass, rounds=200000, salt_size=16)
        u = User(admin_real_name, admin_login, admin_hashed_pw, ["admin", "user"])
        db.session.add(u)
44
        db.session.commit()
Robin Sonnabend's avatar
Robin Sonnabend committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58
    else:
        print("The provided data was invalid.")

@manager.command
def adduser():
    """Add a new user to the system"""
    print("Adding new user:")
    admin_real_name = prompt("Real name")
    admin_login = prompt("Username")
    admin_pass = prompt_pass("Password")
    if admin_real_name is not None and admin_login is not None and admin_pass is not None:
        admin_hashed_pw = pbkdf2_sha256.encrypt(admin_pass, rounds=200000, salt_size=16)
        u = User(admin_real_name, admin_login, admin_hashed_pw, ["user"])
        db.session.add(u)
59
        db.session.commit()
Robin Sonnabend's avatar
Robin Sonnabend committed
60 61 62
    else:
        print("The provided data was invalid.")

63 64
@app.route("/")
def index():
65
    meta = []
66
    return render_layout("index.html", meta=meta)
67 68 69

@app.route("/update")
def update():
Hinrikus Wolf's avatar
Hinrikus Wolf committed
70
    topics = Topic.query.all()
71
    meta = []
Hinrikus Wolf's avatar
Hinrikus Wolf committed
72 73 74 75 76
    for topic in topics:
        ls = speech.query_statements(topic.mode, topic.id)
        no_speaker = Speaker("No Speaker", topic)
        no_statement = Statement(no_speaker, topic)
        meta.append((ls[0] if len(ls) > 0 else (no_statement, no_speaker, ()), topic))
77
    return render_layout("content_index.html", meta=meta)
78 79 80

@app.route("/update.js")
def update_js():
81 82 83
    update_interval = config.UPDATE_INDEX_INTERVAL or 1
    div = "rede-content-div"
    target_url = url_for(".update")
84
    return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="index_")
85 86 87 88 89 90 91 92 93 94

@app.route("/update_time")
def update_time():
    return render_layout("content_time.html")

@app.route("/update_time.js")
def update_time_js():
    update_interval = config.UPDATE_TIME_INTERVAL or 10
    div = "rede-time-div"
    target_url = url_for("update_time")
95
    return render_layout("update.js", update_interval=update_interval, div=div, target_url=target_url, prefix="time_")
96

YSelf Tool's avatar
YSelf Tool committed
97 98 99 100 101 102 103 104 105 106 107 108
@app.route("/login", methods=["GET", "POST"])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = db.session.query(User).filter_by(username=form.username.data).first()
        if (user is not None) and (pbkdf2_sha256.verify(form.password.data, user.password)):
            login_user(user, remember=form.remember_me.data)
            identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))
            flash("Welcome back, {}!".format(user.fullname), "alert-success")
            return redirect(request.args.get("next") or url_for(".index"))
        else:
            flash("Invalid username or wrong password", "alert-error")
109
    return render_layout("login.html", form=form)
YSelf Tool's avatar
YSelf Tool committed
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127

@app.route("/logout", methods=["GET", "POST"])
@login_required
def logout():
    logout_user()
    for key in ("identity.name", "identiy.auth_type"):
        session.pop(key, None)
    identity_changed.send(current_app._get_current_object(), identity=AnonymousIdentity())
    flash("You have been logged out.", "alert-success")
    return redirect(url_for(".index"))

@app.route("/register", methods=["GET", "POST"])
def register():
    form = NewUserForm()
    if form.validate_on_submit():
        length = len(db.session.query(User).filter_by(username=form.username.data).all())
        if length > 0:
            flash("There already is a user with that name.")
128
            return render_layout("register.html", form=form)
YSelf Tool's avatar
YSelf Tool committed
129 130 131 132 133 134
        password = pbkdf2_sha256.encrypt(form.password.data, rounds=200000, salt_size=16)
        user = User(fullname, username, password, [])
        db.session.add(user)
        db.session.commit()
        flash("Your account has been created, you may now log in with it.")
        return redirect(url_for(".login"))
135
    return render_layout("register.html", form=form)
YSelf Tool's avatar
YSelf Tool committed
136

137 138 139 140
@app.route("/icon-font.css")
def icon_font():
    return Response(render_template("icon-font.css"), mimetype="text/css")

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
@identity_loaded.connect_via(app)
def on_identity_loaded(sender, identity):
    # Set the identity user object
    identity.user = current_user
    
    # Add the UserNeed to the identity
    if hasattr(current_user, "id"):
        identity.provides.add(UserNeed(current_user.id))
    
    # Assuming the User Model has a list of roles, update the identity
    # with the roles that the user provides
    if hasattr(current_user, "roles") and current_user.roles is not None:
        for role in current_user.roles:
            identity.provides.add(RoleNeed(role))

@login_manager.user_loader
def load_user(user_id):
    return db.session.query(User).filter_by(id=user_id).first()

160
if __name__ == "__main__":
161
    manager.run()