add some group management
This commit is contained in:
parent
602127cbdc
commit
026fbf3c58
6 changed files with 157 additions and 21 deletions
|
@ -2,9 +2,17 @@ from json import load
|
||||||
from os import environ
|
from os import environ
|
||||||
|
|
||||||
from flask import Flask, flash, redirect, request, session, url_for
|
from flask import Flask, flash, redirect, request, session, url_for
|
||||||
|
from ldap3 import ALL_ATTRIBUTES
|
||||||
from ldap3.core.exceptions import LDAPException
|
from ldap3.core.exceptions import LDAPException
|
||||||
|
|
||||||
from .helpers.ldap import login_required, try_auth, get_user, template, update_user
|
from .helpers.flask import template
|
||||||
|
from .helpers.ldap import (
|
||||||
|
admin_required,
|
||||||
|
get_user,
|
||||||
|
login_required,
|
||||||
|
try_auth,
|
||||||
|
update_user,
|
||||||
|
)
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = environ.get("FLASK_SECRET_KEY", default="test")
|
app.secret_key = environ.get("FLASK_SECRET_KEY", default="test")
|
||||||
|
@ -66,7 +74,7 @@ def selfservice(ldap):
|
||||||
request.form["givenName"],
|
request.form["givenName"],
|
||||||
request.form["sn"],
|
request.form["sn"],
|
||||||
),
|
),
|
||||||
"mail": request.form["mail"]
|
"mail": request.form["mail"],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
flash("data updated")
|
flash("data updated")
|
||||||
|
@ -82,3 +90,44 @@ def selfservice(ldap):
|
||||||
flash(e)
|
flash(e)
|
||||||
|
|
||||||
return template(ldap, "selfservice.html")
|
return template(ldap, "selfservice.html")
|
||||||
|
|
||||||
|
|
||||||
|
@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):
|
||||||
|
if request.method == "POST":
|
||||||
|
if request.form.get("remove"):
|
||||||
|
flash(
|
||||||
|
f"did not remove {request.form['remove']} because not yet implemented"
|
||||||
|
)
|
||||||
|
|
||||||
|
return redirect(url_for("group_edit", ou=ou))
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
|
38
ldap_frontend/helpers/flask.py
Normal file
38
ldap_frontend/helpers/flask.py
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
from functools import wraps
|
||||||
|
from json import load
|
||||||
|
from os import environ
|
||||||
|
|
||||||
|
from flask import redirect, render_template, session, url_for
|
||||||
|
|
||||||
|
from .ldap import get_user
|
||||||
|
|
||||||
|
with open(environ["APP_CONFIG"]) as f:
|
||||||
|
APP_CONFIG = load(f)
|
||||||
|
|
||||||
|
|
||||||
|
def template(ldap, name, **kwargs):
|
||||||
|
user = None
|
||||||
|
is_admin = False
|
||||||
|
|
||||||
|
if ldap:
|
||||||
|
user = get_user(ldap, session["username"])
|
||||||
|
|
||||||
|
ldap.search(
|
||||||
|
APP_CONFIG["ldap"]["user_base"],
|
||||||
|
APP_CONFIG["template"]["group_admin"].format(user["uid"]),
|
||||||
|
attributes=["uid"],
|
||||||
|
)
|
||||||
|
if len(ldap.entries) == 1:
|
||||||
|
is_admin = True
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
name,
|
||||||
|
APP_CONFIG=APP_CONFIG,
|
||||||
|
CURRENT_USER=user,
|
||||||
|
USER_IS_ADMIN=is_admin,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotFoundException(Exception):
|
||||||
|
pass
|
|
@ -2,9 +2,8 @@ from functools import wraps
|
||||||
from json import load
|
from json import load
|
||||||
from os import environ
|
from os import environ
|
||||||
|
|
||||||
from flask import redirect, session, url_for, render_template
|
from flask import redirect, session, url_for
|
||||||
from ldap3 import ALL, Connection, Server
|
from ldap3 import ALL, ALL_ATTRIBUTES, MODIFY_REPLACE, Connection, Server
|
||||||
from ldap3 import ALL_ATTRIBUTES, MODIFY_REPLACE
|
|
||||||
from ldap3.core.exceptions import LDAPException
|
from ldap3.core.exceptions import LDAPException
|
||||||
|
|
||||||
with open(environ["APP_CONFIG"]) as f:
|
with open(environ["APP_CONFIG"]) as f:
|
||||||
|
@ -21,7 +20,7 @@ def login_required(func):
|
||||||
):
|
):
|
||||||
ldap = connect()
|
ldap = connect()
|
||||||
|
|
||||||
return func(ldap, *args, **kwargs)
|
return func(ldap, **kwargs)
|
||||||
else:
|
else:
|
||||||
return redirect(url_for("login"))
|
return redirect(url_for("login"))
|
||||||
else:
|
else:
|
||||||
|
@ -41,7 +40,16 @@ def admin_required(func):
|
||||||
):
|
):
|
||||||
ldap = connect()
|
ldap = connect()
|
||||||
|
|
||||||
return func(ldap, *args, **kwargs)
|
ldap.search(
|
||||||
|
APP_CONFIG["ldap"]["user_base"],
|
||||||
|
APP_CONFIG["template"]["group_admin"].format(session["username"]),
|
||||||
|
attributes=["uid"],
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(ldap.entries) == 1:
|
||||||
|
return func(ldap, **kwargs)
|
||||||
|
else:
|
||||||
|
return redirect(url_for("selfservice"))
|
||||||
else:
|
else:
|
||||||
return redirect(url_for("login"))
|
return redirect(url_for("login"))
|
||||||
else:
|
else:
|
||||||
|
@ -89,6 +97,7 @@ def get_user(ldap, username):
|
||||||
else:
|
else:
|
||||||
raise UserNotFoundException(username)
|
raise UserNotFoundException(username)
|
||||||
|
|
||||||
|
|
||||||
def update_user(ldap, username, settings):
|
def update_user(ldap, username, settings):
|
||||||
attrs = {}
|
attrs = {}
|
||||||
for attr, value in settings.items():
|
for attr, value in settings.items():
|
||||||
|
@ -100,18 +109,5 @@ def update_user(ldap, username, settings):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def template(ldap, name, **kwargs):
|
|
||||||
user = None
|
|
||||||
if ldap:
|
|
||||||
user = get_user(ldap, session["username"])
|
|
||||||
|
|
||||||
return render_template(
|
|
||||||
name,
|
|
||||||
APP_CONFIG=APP_CONFIG,
|
|
||||||
CURRENT_USER=user,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class UserNotFoundException(Exception):
|
class UserNotFoundException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
26
ldap_frontend/templates/groups/list.html
Normal file
26
ldap_frontend/templates/groups/list.html
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{% extends "layout/default.html" %}
|
||||||
|
{% block title %}groups{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<table class="table table-hover align-middle">
|
||||||
|
<thead class="table-light">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">group name</th>
|
||||||
|
<th scope="col">group description</th>
|
||||||
|
<th scope="col">member count</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for group in groups|sort %}
|
||||||
|
<tr>
|
||||||
|
{% if USER_IS_ADMIN %}
|
||||||
|
<th scope="row"><a href="{{ url_for("group_edit", ou=group["ou"]) }}">{{ group["ou"] }}</a></th>
|
||||||
|
{% else %}
|
||||||
|
<th scope="row">{{ group["ou"] }}</th>
|
||||||
|
{% endif %}
|
||||||
|
<td>{{ group["description"] }}</td>
|
||||||
|
<td>{{ group["member"]|length }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
27
ldap_frontend/templates/groups/members.html
Normal file
27
ldap_frontend/templates/groups/members.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{% extends "layout/default.html" %}
|
||||||
|
{% block title %}group {{ ou }}{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<table class="table table-hover align-middle">
|
||||||
|
<thead class="table-light">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">uid</th>
|
||||||
|
<th scope="col">cn</th>
|
||||||
|
<th scope="col">remove</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for member in members|sort %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{{ member["uid"] }}</th>
|
||||||
|
<td>{{ member["cn"] }}</td>
|
||||||
|
<td>
|
||||||
|
<form action="{{ url_for("group_edit", ou=ou) }}" method="post">
|
||||||
|
<input type="hidden" name="remove" value="{{ member["uid"] }}">
|
||||||
|
<input type="submit" value="remove" class="btn btn-danger">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
|
@ -23,7 +23,7 @@
|
||||||
<a class="nav-link" href="{{ url_for("selfservice") }}">self service</a>
|
<a class="nav-link" href="{{ url_for("selfservice") }}">self service</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#">groups</a>
|
<a class="nav-link" href="{{ url_for("groups") }}">groups</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<span class="navbar-text navbar-right">Signed in as <em>{{ CURRENT_USER["uid"] }}</em> - <a href="{{ url_for("logout") }}">logout</a></span>
|
<span class="navbar-text navbar-right">Signed in as <em>{{ CURRENT_USER["uid"] }}</em> - <a href="{{ url_for("logout") }}">logout</a></span>
|
||||||
|
|
Loading…
Reference in a new issue