Skip to content

Commit

Permalink
Merge branch 'membership_delete' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
FestplattenSchnitzel committed Nov 14, 2024
2 parents 0f8fab0 + 4db0f15 commit 89f6fdd
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
15 changes: 15 additions & 0 deletions pycroft/lib/membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,21 @@ def remove_member_of(
user=user, author=processor)


def delete_membership(
session: Session,
membership_id: int,
processor: User,
) -> None:
membership = session.get(Membership, membership_id)
session.delete(membership)
message = deferred_gettext("Deleted membership of group {group}.")
log_user_event(
message.format(group=membership.group.name).to_json(),
user=membership.user,
author=processor,
)


@with_transaction
def edit_property_group(
group: PropertyGroup, name: str, permission_level: int, processor: User
Expand Down
79 changes: 78 additions & 1 deletion web/blueprints/user/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
)
from flask.typing import ResponseReturnValue
from flask_login import current_user
from flask_wtf import FlaskForm
from markupsafe import Markup

import pycroft.lib.search
Expand All @@ -44,7 +45,12 @@
from pycroft.helpers.net import ip_regex, mac_regex
from pycroft.lib.facilities import get_room
from pycroft.lib.logging import log_user_event
from pycroft.lib.membership import make_member_of, remove_member_of, change_membership_active_during
from pycroft.lib.membership import (
make_member_of,
remove_member_of,
change_membership_active_during,
delete_membership,
)
from pycroft.lib.traffic import get_users_with_highest_traffic
from pycroft.lib.user import encode_type1_user_id, encode_type2_user_id, \
traffic_history, generate_user_sheet, get_blocked_groups, \
Expand Down Expand Up @@ -458,6 +464,13 @@ def user_show_groups_json(
membership_id=membership.id,
)
),
url_delete=(
url_delete := url_for(
".membership_delete",
user_id=user_id,
membership_id=membership.id,
)
),
url_end=(
url_end := (
url_for(
Expand Down Expand Up @@ -488,6 +501,18 @@ def user_show_groups_json(
]
if active
else []
)
+ (
[
BtnColResponse(
href=url_delete,
title="Löschen",
icon="fa-trash",
btn_class="btn-link",
)
]
if session.utcnow() <= membership.active_during.begin
else []
),
)
for membership, granted, denied in memberships
Expand Down Expand Up @@ -752,6 +777,58 @@ def default_response(refill_form_data: bool = False) -> ResponseReturnValue:
return redirect(url_for(".user_show", user_id=user.id))


@bp.route("/<int:user_id>/delete_membership/<int:membership_id>/", methods=["GET", "POST"])
@access.require("groups_change_membership")
def membership_delete(user_id: int, membership_id: int) -> ResponseReturnValue:
membership = get_membership_or_404(membership_id)
assert isinstance(membership.group, PropertyGroup)
if membership.group.permission_level > current_user.permission_level:
flash(
"Eine Bearbeitung von Gruppenmitgliedschaften für Gruppen mit "
"höherem Berechtigungslevel ist nicht möglich.",
"error",
)
abort(403)
if session.utcnow() >= membership.active_during.begin:
flash("Nur Mitgliedschaften, die in der Zukunft liegen, können gelöscht werden.", "error")
abort(403)
form = FlaskForm()

def default_response() -> ResponseReturnValue:
form_args = {
"form": form,
"cancel_to": url_for("user.user_show", user_id=membership.user_id, _anchor="groups"),
"submit_text": "Löschen",
"actions_offset": 0,
}

return render_template(
"generic_form.html",
page_title=(
"Mitgliedschaft {} für "
"{} löschen".format(membership.group.name, membership.user.name)
),
membership_id=membership_id,
user=membership.user,
form=form,
form_args=form_args,
)

if not form.is_submitted():
return default_response()

with abort_on_error(default_response), session.session.begin_nested():
delete_membership(
session=session.session,
membership_id=membership_id,
processor=current_user,
)
session.session.commit()

flash("Mitgliedschaft erfolgreich gelöscht.", "success")
return redirect(url_for("user.user_show", user_id=membership.user_id, _anchor="groups"))


@bp.route('/<int:user_id>/edit_membership/<int:membership_id>', methods=['GET', 'POST'])
@access.require('groups_change_membership')
def edit_membership(user_id: int, membership_id: int) -> ResponseReturnValue:
Expand Down
1 change: 1 addition & 0 deletions web/blueprints/user/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class MembershipRow(BaseModel):
ends_at: DateColResponse
url_edit: str
url_end: str | None = None
url_delete: str | None = None
actions: list[BtnColResponse]
# used by membershipRowAttributes
grants: list[str | None]
Expand Down

0 comments on commit 89f6fdd

Please sign in to comment.