ldap-frontend/ldap_frontend/__init__.py

246 lines
7 KiB
Python
Raw Normal View History

2021-12-21 07:30:36 +00:00
from json import load
from os import environ
from flask import Flask, flash, redirect, request, session, url_for
2021-12-23 08:14:27 +00:00
from flask_babel import Babel, gettext
from flask_wtf.csrf import CSRFError, CSRFProtect
2021-12-21 09:20:16 +00:00
from ldap3 import ALL_ATTRIBUTES, MODIFY_ADD, MODIFY_DELETE
2021-12-21 07:30:36 +00:00
from ldap3.core.exceptions import LDAPException
2021-12-21 10:02:48 +00:00
from ldap3.utils.dn import escape_rdn
2021-12-21 07:30:36 +00:00
2021-12-21 08:27:25 +00:00
from .helpers.flask import template
from .helpers.ldap import (
admin_required,
get_user,
login_required,
try_auth,
update_user,
2021-12-21 08:58:57 +00:00
update_user_password,
2021-12-21 08:27:25 +00:00
)
2021-12-21 07:30:36 +00:00
app = Flask(__name__)
app.secret_key = environ.get("FLASK_SECRET_KEY", default="test")
2021-12-23 08:14:27 +00:00
app.config["LANGUAGES"] = {"en": "English", "de": "Deutsch"}
babel = Babel(app)
2021-12-21 15:57:39 +00:00
csrf = CSRFProtect(app)
2021-12-21 07:30:36 +00:00
with open(environ["APP_CONFIG"]) as f:
APP_CONFIG = load(f)
2021-12-23 08:14:27 +00:00
@babel.localeselector
def get_locale():
return request.accept_languages.best_match(app.config["LANGUAGES"].keys())
2021-12-21 15:57:39 +00:00
@app.errorhandler(CSRFError)
def handle_csrf_error(e):
2021-12-23 08:14:27 +00:00
flash(
gettext("CRSF validation error. For your own safety, you have been logged out.")
)
2021-12-21 15:57:39 +00:00
session["is_logged_in"] = False
session["username"] = ""
session["password"] = ""
return redirect(url_for("login"))
2021-12-21 07:30:36 +00:00
@app.route("/")
def slash():
2021-12-23 08:14:27 +00:00
if session.get("is_logged_in"):
return redirect(url_for("selfservice"))
2021-12-21 07:30:36 +00:00
return redirect(url_for("login"))
@app.route("/login", methods=["GET", "POST"])
def login():
session["is_logged_in"] = False
if request.method == "POST":
if try_auth(
2021-12-21 10:02:48 +00:00
escape_rdn(request.form["username"]),
2021-12-21 07:30:36 +00:00
request.form["password"],
):
session["is_logged_in"] = True
2021-12-21 10:02:48 +00:00
session["username"] = escape_rdn(request.form["username"])
2021-12-21 07:30:36 +00:00
session["password"] = request.form["password"]
2021-12-23 08:14:27 +00:00
flash(gettext("logged in"))
2021-12-21 07:30:36 +00:00
return redirect(url_for("selfservice"))
else:
2021-12-23 08:14:27 +00:00
flash(gettext("username or password is wrong"))
2021-12-21 07:30:36 +00:00
return template(None, "login.html")
@app.route("/logout")
def logout():
session["is_logged_in"] = False
session["username"] = ""
session["password"] = ""
2021-12-23 08:14:27 +00:00
flash(gettext("you have been logged out"))
2021-12-21 07:30:36 +00:00
return redirect(url_for("login"))
@app.route("/selfservice", methods=["GET", "POST"])
@login_required
def selfservice(ldap):
if request.method == "POST":
2021-12-21 08:58:57 +00:00
if request.form.get("userdata"):
try:
update_user(
ldap,
session["username"],
{
"givenName": request.form["givenName"],
"sn": request.form["sn"],
"cn": "{} {}".format(
request.form["givenName"],
request.form["sn"],
),
"externalMail": request.form["externalMail"],
2021-12-21 08:58:57 +00:00
},
)
2021-12-23 08:14:27 +00:00
flash(gettext("user data was updated"))
2021-12-21 08:58:57 +00:00
except LDAPException as e:
app.logger.error(
"Updating {} failed: {}\n{}".format(
APP_CONFIG["template"]["user_dn"].format(session["username"]),
repr(e),
repr(request.form),
2021-12-21 07:30:36 +00:00
),
2021-12-21 08:58:57 +00:00
)
flash(e)
elif request.form.get("passwordchange"):
validated = (True,)
if not try_auth(
session["username"],
request.form["current"],
):
validated = False
2021-12-23 08:14:27 +00:00
flash(gettext("current password does not match the one stored"))
2021-12-21 08:58:57 +00:00
if request.form["new"] != request.form["repeat"]:
validated = False
2021-12-23 08:14:27 +00:00
flash(gettext("new passwords do not match"))
2021-12-21 08:58:57 +00:00
if len(request.form["new"]) < 12:
validated = False
2021-12-23 08:14:27 +00:00
flash(gettext("new password must be atleast 12 characters long"))
2021-12-21 08:58:57 +00:00
if validated:
try:
update_user_password(
ldap,
session["username"],
request.form["new"],
)
session["password"] = request.form["new"]
2021-12-23 08:14:27 +00:00
flash(gettext("your password was changed"))
2021-12-21 08:58:57 +00:00
except LDAPException as e:
app.logger.error(
2021-12-21 10:02:48 +00:00
"Updating {} failed: {}".format(
2021-12-21 08:58:57 +00:00
APP_CONFIG["template"]["user_dn"].format(
session["username"]
),
repr(e),
),
)
flash(e)
return redirect(url_for("selfservice"))
2021-12-21 07:30:36 +00:00
return template(ldap, "selfservice.html")
2021-12-21 08:27:25 +00:00
@app.route("/groups", methods=["GET"])
@login_required
def groups(ldap):
ldap.search(
APP_CONFIG["ldap"]["group_base"],
"(objectclass=groupOfNames)",
attributes=ALL_ATTRIBUTES,
)
return template(
ldap,
"groups/list.html",
groups=ldap.entries,
)
@app.route("/groups/<ou>", methods=["GET", "POST"])
@admin_required
def group_edit(ldap, ou):
2021-12-21 10:02:48 +00:00
ou = escape_rdn(ou)
2021-12-21 08:27:25 +00:00
if request.method == "POST":
if request.form.get("remove"):
2021-12-21 09:20:16 +00:00
ldap.modify(
APP_CONFIG["template"]["group_dn"].format(ou),
{
"member": [
(
MODIFY_DELETE,
APP_CONFIG["template"]["user_dn"].format(
2021-12-21 10:02:48 +00:00
escape_rdn(request.form["remove"])
2021-12-21 09:20:16 +00:00
),
)
]
},
)
2021-12-23 08:14:27 +00:00
flash(
gettext(
"%(user)s was removed from %(ou)s",
user=request.form["remove"],
ou=ou,
)
)
2021-12-21 09:20:16 +00:00
elif request.form.get("add"):
ldap.modify(
APP_CONFIG["template"]["group_dn"].format(ou),
{
"member": [
(
MODIFY_ADD,
APP_CONFIG["template"]["user_dn"].format(
2021-12-21 10:02:48 +00:00
escape_rdn(request.form["add"])
2021-12-21 09:20:16 +00:00
),
)
]
},
2021-12-21 08:27:25 +00:00
)
2021-12-23 08:14:27 +00:00
flash(
gettext(
2021-12-23 15:28:10 +00:00
"%(user)s was added to %(ou)s", user=request.form["add"], ou=ou
2021-12-23 08:14:27 +00:00
)
)
2021-12-21 08:27:25 +00:00
return redirect(url_for("group_edit", ou=ou))
2021-12-21 09:20:16 +00:00
ldap.search(
APP_CONFIG["ldap"]["user_base"],
APP_CONFIG["template"]["group_nonmembers"].format(ou),
attributes=["cn", "uid"],
)
users = ldap.entries
2021-12-21 08:27:25 +00:00
ldap.search(
APP_CONFIG["ldap"]["user_base"],
APP_CONFIG["template"]["group_members"].format(ou),
attributes=ALL_ATTRIBUTES,
)
return template(
ldap,
"groups/members.html",
members=ldap.entries,
ou=ou,
2021-12-21 09:20:16 +00:00
other_users=users,
2021-12-21 08:27:25 +00:00
)