admin: add group list and group details pages
parent
dc2bb81f61
commit
bdd0de0b53
|
@ -54,7 +54,7 @@ def _get_groupped_user_list(conn):
|
||||||
@bp.route('/admin/')
|
@bp.route('/admin/')
|
||||||
@admin_required
|
@admin_required
|
||||||
def admin_view():
|
def admin_view():
|
||||||
return flask.redirect('/admin/users/')
|
return flask.render_template('admin/index.html')
|
||||||
|
|
||||||
@bp.route('/admin/users/')
|
@bp.route('/admin/users/')
|
||||||
@admin_required
|
@admin_required
|
||||||
|
@ -62,7 +62,7 @@ def admin_users_view():
|
||||||
conn = context.get_connection()
|
conn = context.get_connection()
|
||||||
groups = _get_groupped_user_list(conn)
|
groups = _get_groupped_user_list(conn)
|
||||||
|
|
||||||
return flask.render_template('admin/list.html', groups=groups)
|
return flask.render_template('admin/users.html', groups=groups)
|
||||||
|
|
||||||
def _get_profile(conn, uid):
|
def _get_profile(conn, uid):
|
||||||
results = conn.search_s(ldaputils.user_dn(uid), ldap.SCOPE_SUBTREE)
|
results = conn.search_s(ldaputils.user_dn(uid), ldap.SCOPE_SUBTREE)
|
||||||
|
@ -102,3 +102,39 @@ def admin_user_view(uid):
|
||||||
groups = _get_groups_of(conn, uid)
|
groups = _get_groups_of(conn, uid)
|
||||||
|
|
||||||
return flask.render_template('admin/user.html', uid=uid, profile=_format_profile(profile), groups=groups)
|
return flask.render_template('admin/user.html', uid=uid, profile=_format_profile(profile), groups=groups)
|
||||||
|
|
||||||
|
@bp.route('/admin/groups/')
|
||||||
|
@admin_required
|
||||||
|
def admin_groups_view():
|
||||||
|
conn = context.get_connection()
|
||||||
|
|
||||||
|
# no obvious way to filter out groups that are just a per-user-group
|
||||||
|
# (not super useful to look at them)
|
||||||
|
# so we'll filter them out by name yolo
|
||||||
|
all_users = _get_user_list(conn)
|
||||||
|
all_uids = set([uid for uid, cn in all_users])
|
||||||
|
|
||||||
|
groups = [
|
||||||
|
attrs['cn'][0].decode()
|
||||||
|
for group_dn, attrs in
|
||||||
|
conn.search_s(config.ldap_base, ldap.SCOPE_SUBTREE, 'objectClass=groupOfUniqueNames')
|
||||||
|
]
|
||||||
|
|
||||||
|
filter_groups = filter((lambda cn: cn not in all_uids), groups)
|
||||||
|
|
||||||
|
return flask.render_template('admin/groups.html', groups=filter_groups)
|
||||||
|
|
||||||
|
def _get_group(conn, name):
|
||||||
|
results = conn.search_s(ldaputils.group_dn(name), ldap.SCOPE_SUBTREE)
|
||||||
|
return ldaputils.normalized_entries(results)[0]
|
||||||
|
|
||||||
|
@bp.route('/admin/groups/<name>')
|
||||||
|
@admin_required
|
||||||
|
def admin_group_view(name):
|
||||||
|
ldaputils.validate_name(name)
|
||||||
|
conn = context.get_connection()
|
||||||
|
|
||||||
|
group_attrs = _get_group(conn, name)
|
||||||
|
members = _get_user_list(conn, f'memberOf={ldaputils.group_dn(name)}')
|
||||||
|
|
||||||
|
return flask.render_template('admin/group.html', name=name, attributes=_format_profile(group_attrs), members=members)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
{% extends 'basic.html' %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>Group: {{ name }}</h1>
|
||||||
|
|
||||||
|
<div style="margin-bottom: 10px">
|
||||||
|
<a class="btn btn-default" href="/admin/groups" role="button">Back</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>Members:</strong>
|
||||||
|
{% for uid, cn in members %}
|
||||||
|
<a href="/admin/users/{{ uid }}">{{ uid }}</a>,
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Full LDAP record:</p>
|
||||||
|
|
||||||
|
<table class="table profile-table">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Attribute</th>
|
||||||
|
<th scope="col">Attribute</th>
|
||||||
|
<th scope="col" class="profile-table-value">Value</th>
|
||||||
|
</tr>
|
||||||
|
{% for attr, attr_readable, value in attributes %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ attr }}</td>
|
||||||
|
<td>{{ attr_readable if attr_readable else '' }}</td>
|
||||||
|
<td class="profile-table-value">{{ value }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
<style type="text/css">
|
||||||
|
.profile-table td, .profile-table th {
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
.profile-table td.profile-table-value,
|
||||||
|
.profile-table th.profile-table-value {
|
||||||
|
width: max-content;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{% extends 'basic.html' %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<a class="btn btn-default" href="/admin">Back</a>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for group in groups %}
|
||||||
|
<li><a href="/admin/groups/{{ group }}">{{ group }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{% extends 'basic.html' %}
|
||||||
|
{% block content %}
|
||||||
|
<p>Good evening, professor {{ session['username'] }}.</p>
|
||||||
|
|
||||||
|
<a class="btn btn-default" id="new-user-btn">Add new user</a>
|
||||||
|
<a class="btn btn-default" href="/admin/users">View all users</a>
|
||||||
|
<a class="btn btn-default" href="/admin/groups">View all groups</a>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
<script>
|
||||||
|
document.querySelector('#new-user-btn').addEventListener('click', function() {
|
||||||
|
alert('lol not yet')
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -3,7 +3,7 @@
|
||||||
<h1>User: {{ uid }}</h1>
|
<h1>User: {{ uid }}</h1>
|
||||||
|
|
||||||
<div style="margin-bottom: 10px">
|
<div style="margin-bottom: 10px">
|
||||||
<a class="btn btn-default" href="/admin" role="button">Back</a>
|
<a class="btn btn-default" href="/admin/users" role="button">Back</a>
|
||||||
|
|
||||||
<a class="btn btn-default" href="https://kasownik.hackerspace.pl/admin/member/{{ uid }}" role="button" target="_blank">View user in Kasownik</a>
|
<a class="btn btn-default" href="https://kasownik.hackerspace.pl/admin/member/{{ uid }}" role="button" target="_blank">View user in Kasownik</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{% extends 'basic.html' %}
|
{% extends 'basic.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<p>Good evening, professor {{ session['username'] }}. All LDAP accounts:</p>
|
|
||||||
|
<a class="btn btn-default" href="/admin">Back</a>
|
||||||
|
|
||||||
{% for group_name, users in groups %}
|
{% for group_name, users in groups %}
|
||||||
<h2>{{ group_name }}</h2>
|
<h2>{{ group_name }}</h2>
|
Loading…
Reference in New Issue