Skip to content
Snippets Groups Projects
Commit 2a08b950 authored by Lars Beckers's avatar Lars Beckers
Browse files

improve on pep8 conformance

parent 7f85e9fb
No related branches found
No related tags found
No related merge requests found
[flake8]
max-line-length=160
import datetime
SECRET_KEY = b'' SECRET_KEY = b''
SQLALCHEMY_DATABASE_URI = '' SQLALCHEMY_DATABASE_URI = ''
DEBUG = True DEBUG = True
PORT = 5001 PORT = 5001
SESSION_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True
import datetime
REMEMBER_COOKIE_NAME = 'remember_token' REMEMBER_COOKIE_NAME = 'remember_token'
REMEMBER_COOKIE_DURATION = datetime.timedelta(30) REMEMBER_COOKIE_DURATION = datetime.timedelta(30)
REMEMBER_COOKIE_DOMAIN = None REMEMBER_COOKIE_DOMAIN = None
...@@ -28,10 +29,7 @@ BRANDING_APP_URL = 'https://lehrpreis.example.com' ...@@ -28,10 +29,7 @@ BRANDING_APP_URL = 'https://lehrpreis.example.com'
BRANDING_ORG_NAME = 'Example Oragnization' BRANDING_ORG_NAME = 'Example Oragnization'
BRANDING_CONTACT = 'it@example-organisation.com' BRANDING_CONTACT = 'it@example-organisation.com'
BRANDING_LOGO = 'logo.png' BRANDING_LOGO = 'logo.png'
BRANDING_INFORMATION = {'de': '''<h3>Die Regeln</h3> BRANDING_INFORMATION = {'de': '<p>Dieser Text wurde bisher nicht übersetzt.</p>',
<p>Du kannst jeden Dozenten dessen Lehre dir besonders gefallen hat nominieren. Vorraussetzung ist, dass dieser aus der Informatik stammt. Also Mathe-Service-Dozenten sind nicht zugelassen. Auch Dozenten aus Anwendungsfächern werden nicht geehrt.</p>
<p>Die Kategorie sollte auch passen. Professoren und Post-Docs, die eigenständig eine Veranstaltung betreuen, gehören in die Kategorie "Prof". Mitarbeiter, die Übungen betreuen, Vorlesungen nur vertretungsweise halten oder sonstwie unterstützend tätig sind in die Kategorie "WM".</p>
<p>Danke für deine Aufmerksamkeit!</p>''',
'en': '<p>This text was not yet translated.</p>'} 'en': '<p>This text was not yet translated.</p>'}
MAIL_ENABLED = True MAIL_ENABLED = True
......
#!/usr/bin/env python3 #!/usr/bin/env python3
from flask import Flask, Response, redirect, render_template, flash, url_for, session, request from flask import Flask, redirect, render_template, flash, url_for, session, request
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_login import login_required, current_user, LoginManager, login_user, logout_user, UserMixin from flask_login import login_required, current_user, LoginManager, login_user, logout_user, UserMixin
from flask_wtf import FlaskForm as Form from flask_wtf import FlaskForm as Form
from flask_babel import Babel, gettext, ngettext, format_date, lazy_gettext, force_locale from flask_babel import Babel, gettext, lazy_gettext, force_locale
from flask_babel import refresh as babel_refresh from flask_babel import refresh as babel_refresh
from wtforms import StringField, BooleanField, PasswordField, DateField, SelectField from wtforms import StringField, BooleanField, PasswordField, DateField, SelectField
from wtforms.validators import Optional, InputRequired from wtforms.validators import Optional, InputRequired
import smtplib import smtplib
import email
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
import ssl import ssl
import ldap3 import ldap3
from ldap3.utils.dn import parse_dn
from sqlalchemy import String, Integer, Boolean, Date, ForeignKey from sqlalchemy import String, Integer, Boolean, Date, ForeignKey
from sqlalchemy.orm import relationship, backref from sqlalchemy.orm import relationship
import re
import functools import functools
import datetime import datetime
import config import config
...@@ -33,12 +30,13 @@ login_manager.login_message_category = 'alert-info' ...@@ -33,12 +30,13 @@ login_manager.login_message_category = 'alert-info'
# login_manager.session_protection = 'strong' # basic # login_manager.session_protection = 'strong' # basic
babel = Babel(app) babel = Babel(app)
@babel.localeselector @babel.localeselector
def get_locale(): def get_locale():
if not ('lang' in session): if not ('lang' in session):
session['lang'] = request.accept_languages.best_match(['de', 'en']) session['lang'] = request.accept_languages.best_match(['de', 'en'])
return session['lang'] return session['lang']
app.jinja_env.globals['get_locale'] = get_locale
# http://flask.pocoo.org/snippets/120/ # http://flask.pocoo.org/snippets/120/
class back(): class back():
...@@ -60,8 +58,12 @@ class back(): ...@@ -60,8 +58,12 @@ class back():
@staticmethod @staticmethod
def redirect(default=default_view, cookie=cookie): def redirect(default=default_view, cookie=cookie):
return redirect(back.url(default, cookie)) return redirect(back.url(default, cookie))
app.jinja_env.globals['get_locale'] = get_locale
back = back() back = back()
@app.route('/switch-language') @app.route('/switch-language')
def switch_lang(): def switch_lang():
lang = get_locale() lang = get_locale()
...@@ -70,6 +72,7 @@ def switch_lang(): ...@@ -70,6 +72,7 @@ def switch_lang():
flash(gettext('The language was changed to English.'), 'alert-success') flash(gettext('The language was changed to English.'), 'alert-success')
return back.redirect() return back.redirect()
class User(UserMixin): class User(UserMixin):
def __init__(self, name, domain): def __init__(self, name, domain):
self.user = name self.user = name
...@@ -82,17 +85,18 @@ class User(UserMixin): ...@@ -82,17 +85,18 @@ class User(UserMixin):
def get(user_id): def get(user_id):
return User(user_id, '') return User(user_id, '')
@login_manager.user_loader @login_manager.user_loader
def load_user(user_id): def load_user(user_id):
return User.get(user_id) return User.get(user_id)
@app.route('/login', methods=['GET', 'POST']) @app.route('/login', methods=['GET', 'POST'])
def login(): def login():
form = LoginForm() form = LoginForm()
if form.validate_on_submit(): if form.validate_on_submit():
auth_manager = ADManager(host=config.AD_HOST, domain=config.AD_DOMAIN, auth_manager = ADManager(host=config.AD_HOST, domain=config.AD_DOMAIN, user_dn=config.AD_USER_DN,
user_dn=config.AD_USER_DN, group_dn=config.AD_GROUP_DN, group_dn=config.AD_GROUP_DN, ca_cert=config.AD_CA_CERT)
ca_cert=config.AD_CA_CERT)
if auth_manager.authenticate(form.username.data, form.password.data): if auth_manager.authenticate(form.username.data, form.password.data):
user = User(form.username.data, auth_manager.domain) user = User(form.username.data, auth_manager.domain)
login_user(user, remember=form.remember_me.data) login_user(user, remember=form.remember_me.data)
...@@ -103,6 +107,7 @@ def login(): ...@@ -103,6 +107,7 @@ def login():
return back.redirect() return back.redirect()
return render_template('login.html', form=form) return render_template('login.html', form=form)
@app.route("/logout") @app.route("/logout")
@login_required @login_required
def logout(): def logout():
...@@ -110,15 +115,13 @@ def logout(): ...@@ -110,15 +115,13 @@ def logout():
session.pop('groups') session.pop('groups')
return back.redirect() return back.redirect()
class ADManager: class ADManager:
def __init__(self, host, domain, user_dn, group_dn, def __init__(self, host, domain, user_dn, group_dn, port=636, use_ssl=True, ca_cert=None):
port=636, use_ssl=True, ca_cert=None):
tls_config = ldap3.Tls(validate=ssl.CERT_REQUIRED) tls_config = ldap3.Tls(validate=ssl.CERT_REQUIRED)
if ca_cert is not None: if ca_cert is not None:
tls_config = ldap3.Tls(validate=ssl.CERT_REQUIRED, tls_config = ldap3.Tls(validate=ssl.CERT_REQUIRED, ca_certs_file=ca_cert)
ca_certs_file=ca_cert) self.server = ldap3.Server(host, port=port, use_ssl=use_ssl, tls=tls_config)
self.server = ldap3.Server(host, port=port, use_ssl=use_ssl,
tls=tls_config)
self.domain = domain self.domain = domain
self.user_dn = user_dn self.user_dn = user_dn
self.group_dn = group_dn self.group_dn = group_dn
...@@ -140,7 +143,7 @@ class ADManager: ...@@ -140,7 +143,7 @@ class ADManager:
for result in user_reader.search(): for result in user_reader.search():
if result.userAccountControl in [546, 514, 66050, 66082]: if result.userAccountControl in [546, 514, 66050, 66082]:
return False return False
if not config.USER_GROUP in self.groups(username, password): if config.USER_GROUP not in self.groups(username, password):
return False return False
return True return True
except ldap3.core.exceptions.LDAPSocketOpenError: except ldap3.core.exceptions.LDAPSocketOpenError:
...@@ -153,6 +156,7 @@ class ADManager: ...@@ -153,6 +156,7 @@ class ADManager:
name_filter = "cn:={}".format(username) name_filter = "cn:={}".format(username)
user_reader = ldap3.Reader(connection, obj_def, self.user_dn, name_filter) user_reader = ldap3.Reader(connection, obj_def, self.user_dn, name_filter)
group_def = ldap3.ObjectDef("group", connection) group_def = ldap3.ObjectDef("group", connection)
def _yield_recursive_groups(group_dn): def _yield_recursive_groups(group_dn):
group_reader = ldap3.Reader(connection, group_def, group_dn, None) group_reader = ldap3.Reader(connection, group_def, group_dn, None)
for entry in group_reader.search(): for entry in group_reader.search():
...@@ -167,10 +171,11 @@ class ADManager: ...@@ -167,10 +171,11 @@ class ADManager:
connection = self.prepare_connection() connection = self.prepare_connection()
connection.bind() connection.bind()
obj_def = ldap3.ObjectDef("group", connection) obj_def = ldap3.ObjectDef("group", connection)
group_reader = ldap3.Reader(connection, obj_def, self.group_dn) reader = ldap3.Reader(connection, obj_def, self.group_dn)
for result in reader.search(): for result in reader.search():
yield result.name.value yield result.name.value
class Instance(db.Model): class Instance(db.Model):
__tablename__ = 'instances' __tablename__ = 'instances'
id = db.Column(Integer, nullable=False, unique=True, index=True, primary_key=True) id = db.Column(Integer, nullable=False, unique=True, index=True, primary_key=True)
...@@ -180,6 +185,7 @@ class Instance(db.Model): ...@@ -180,6 +185,7 @@ class Instance(db.Model):
categories = db.Column(String(255), nullable=False) categories = db.Column(String(255), nullable=False)
nominees = relationship('Nomination', foreign_keys='Nomination.instance_id', backref='instance', cascade="all, delete-orphan") nominees = relationship('Nomination', foreign_keys='Nomination.instance_id', backref='instance', cascade="all, delete-orphan")
class Nomination(db.Model): class Nomination(db.Model):
__tablename__ = 'nominations' __tablename__ = 'nominations'
id = db.Column(Integer, nullable=False, unique=True, index=True, primary_key=True) id = db.Column(Integer, nullable=False, unique=True, index=True, primary_key=True)
...@@ -189,11 +195,14 @@ class Nomination(db.Model): ...@@ -189,11 +195,14 @@ class Nomination(db.Model):
category = db.Column(String(255), nullable=False) category = db.Column(String(255), nullable=False)
instance_id = db.Column(Integer, ForeignKey('instances.id'), nullable=False) instance_id = db.Column(Integer, ForeignKey('instances.id'), nullable=False)
@app.route('/', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST'])
@back.anchor @back.anchor
def main(): def main():
today = datetime.date.today() today = datetime.date.today()
inst = Instance.query.filter_by(enabled=True).filter(Instance.date > today).order_by(Instance.date.asc()).first() or Instance.query.filter(Instance.date > today).order_by(Instance.date.asc()).first() inst = Instance.query.filter_by(enabled=True).filter(Instance.date > today).order_by(
Instance.date.asc()).first() or Instance.query.filter(Instance.date > today).order_by(
Instance.date.asc()).first()
form = NominateForm() form = NominateForm()
form.category.choices = [(category.strip(), category.strip()) for category in inst.categories.split(';')] if inst else [] form.category.choices = [(category.strip(), category.strip()) for category in inst.categories.split(';')] if inst else []
if form.validate_on_submit(): if form.validate_on_submit():
...@@ -220,6 +229,7 @@ def main(): ...@@ -220,6 +229,7 @@ def main():
s.send_message(mail) s.send_message(mail)
return render_template('main.html', inst=inst, form=form) return render_template('main.html', inst=inst, form=form)
@app.route('/manage', methods=['GET', 'POST']) @app.route('/manage', methods=['GET', 'POST'])
@back.anchor @back.anchor
@login_required @login_required
...@@ -237,6 +247,7 @@ def manage(): ...@@ -237,6 +247,7 @@ def manage():
return redirect(url_for('.manage')) return redirect(url_for('.manage'))
return render_template('manage.html', insts=insts, form=form) return render_template('manage.html', insts=insts, form=form)
@app.route('/manage/nominees/<int:instid>') @app.route('/manage/nominees/<int:instid>')
@back.anchor @back.anchor
@login_required @login_required
...@@ -245,6 +256,7 @@ def nominees(instid): ...@@ -245,6 +256,7 @@ def nominees(instid):
nominees = Nomination.query.filter_by(instance_id=instid).all() nominees = Nomination.query.filter_by(instance_id=instid).all()
return render_template('nominees.html', noms=nominees, inst=inst) return render_template('nominees.html', noms=nominees, inst=inst)
@app.route('/manage/modify/<int:instid>', methods=['GET', 'POST']) @app.route('/manage/modify/<int:instid>', methods=['GET', 'POST'])
@back.anchor @back.anchor
@login_required @login_required
...@@ -261,6 +273,7 @@ def modify(instid): ...@@ -261,6 +273,7 @@ def modify(instid):
return redirect(url_for('.manage')) return redirect(url_for('.manage'))
return render_template('modify.html', inst=inst, form=form) return render_template('modify.html', inst=inst, form=form)
@app.route('/manage/enable/<int:instid>', methods=['GET', 'POST']) @app.route('/manage/enable/<int:instid>', methods=['GET', 'POST'])
@back.anchor @back.anchor
@login_required @login_required
...@@ -274,6 +287,7 @@ def enable(instid): ...@@ -274,6 +287,7 @@ def enable(instid):
return redirect(url_for('.manage')) return redirect(url_for('.manage'))
return render_template('enable.html', inst=inst, form=form) return render_template('enable.html', inst=inst, form=form)
@app.route('/manage/disable/<int:instid>', methods=['GET', 'POST']) @app.route('/manage/disable/<int:instid>', methods=['GET', 'POST'])
@back.anchor @back.anchor
@login_required @login_required
...@@ -287,6 +301,7 @@ def disable(instid): ...@@ -287,6 +301,7 @@ def disable(instid):
return redirect(url_for('.manage')) return redirect(url_for('.manage'))
return render_template('disable.html', inst=inst, form=form) return render_template('disable.html', inst=inst, form=form)
@app.route('/manage/delete/<int:instid>', methods=['GET', 'POST']) @app.route('/manage/delete/<int:instid>', methods=['GET', 'POST'])
@back.anchor @back.anchor
@login_required @login_required
...@@ -306,27 +321,38 @@ class LoginForm(Form): ...@@ -306,27 +321,38 @@ class LoginForm(Form):
password = PasswordField(lazy_gettext('Password'), validators=[InputRequired(lazy_gettext('Please enter your password here.'))]) password = PasswordField(lazy_gettext('Password'), validators=[InputRequired(lazy_gettext('Please enter your password here.'))])
remember_me = BooleanField(lazy_gettext('Keep me logged in.'), validators=[Optional()]) remember_me = BooleanField(lazy_gettext('Keep me logged in.'), validators=[Optional()])
class NominateForm(Form): class NominateForm(Form):
person = StringField(lazy_gettext('Nominee'), validators=[InputRequired(lazy_gettext('Please enter the name of the person you want to nominate.'))]) person = StringField(lazy_gettext('Nominee'), validators=[InputRequired(lazy_gettext('Please enter the name of the person you want to nominate.'))])
category = SelectField(lazy_gettext('Category'), validators=[InputRequired(lazy_gettext('Please select the category you want to nominate the person in.'))]) category = SelectField(lazy_gettext('Category'), validators=[InputRequired(lazy_gettext('Please select the category you want to nominate the person in.'))])
module = StringField(lazy_gettext('Module'), validators=[InputRequired(lazy_gettext('Please enter the module/course/lecture that was outstanding.'))]) module = StringField(lazy_gettext('Module'), validators=[InputRequired(lazy_gettext('Please enter the module/course/lecture that was outstanding.'))])
reason = StringField(lazy_gettext('Reason'), validators=[InputRequired(lazy_gettext('Please enter a reason why the nominee shall be awarded.'))]) reason = StringField(lazy_gettext('Reason'), validators=[InputRequired(lazy_gettext('Please enter a reason why the nominee shall be awarded.'))])
tos = BooleanField(lazy_gettext('The nominee is eligible for the award.'), validators=[InputRequired(lazy_gettext('Please verify the eligibility beforehand.'))]) tos = BooleanField(lazy_gettext('The nominee is eligible for the award.'), validators=[InputRequired(
lazy_gettext('Please verify the eligibility beforehand.'))])
class InstanceForm(Form): class InstanceForm(Form):
name = StringField(lazy_gettext('Name'), validators=[InputRequired(lazy_gettext('Please enter the instances name, e.g. a semester identifier.'))]) name = StringField(lazy_gettext('Name'), validators=[InputRequired(lazy_gettext('Please enter the instances name, e.g. a semester identifier.'))])
enabled = BooleanField(lazy_gettext('Enable'), validators=[Optional()]) enabled = BooleanField(lazy_gettext('Enable'), validators=[Optional()])
date = DateField(lazy_gettext('Award Date'), description=lazy_gettext('Please use the format YYYY-MM-DD.'), validators=[InputRequired(lazy_gettext('Please enter the date this is instance is awarded.'))]) date = DateField(lazy_gettext('Award Date'),
categories = StringField(lazy_gettext('Categories'), description=lazy_gettext('Please enter one or more nomination categories and seperate them using a semicolon.'), validators=[InputRequired(lazy_gettext('Please enter some categories.'))]) description=lazy_gettext('Please use the format YYYY-MM-DD.'),
validators=[InputRequired(lazy_gettext('Please enter the date this is instance is awarded.'))])
categories = StringField(lazy_gettext('Categories'),
description=lazy_gettext('Please enter one or more nomination categories and seperate them using a semicolon.'),
validators=[InputRequired(lazy_gettext('Please enter some categories.'))])
class EnableForm(Form): class EnableForm(Form):
pass pass
class DisableForm(Form): class DisableForm(Form):
pass pass
class DeleteForm(Form): class DeleteForm(Form):
pass pass
if __name__ == '__main__': if __name__ == '__main__':
app.run(port=config.PORT) app.run(port=config.PORT)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment