From 9b26e7cbf35f77eded0f2feffa43d74bbcb11ca5 Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Thu, 4 Jul 2019 13:16:00 +0200 Subject: [PATCH] Add CRUD views for UserAccess --- todosrht/blueprints/tracker.py | 75 +++++++++++++++++++--- todosrht/templates/tracker-access.html | 88 ++++++++++++++++++++++++++ todosrht/types/useraccess.py | 3 +- 3 files changed, 156 insertions(+), 10 deletions(-) diff --git a/todosrht/blueprints/tracker.py b/todosrht/blueprints/tracker.py index 0b393cd..eae32e6 100644 --- a/todosrht/blueprints/tracker.py +++ b/todosrht/blueprints/tracker.py @@ -6,8 +6,8 @@ from todosrht.access import get_tracker from todosrht.search import apply_search from todosrht.tickets import get_last_seen_times, get_comment_counts from todosrht.tickets import submit_ticket -from todosrht.types import TicketSubscription -from todosrht.types import Event +from todosrht.types import TicketSubscription, User +from todosrht.types import Event, UserAccess from todosrht.types import Tracker, Ticket, TicketAccess from todosrht.types import Label, TicketLabel from todosrht.urls import tracker_url, ticket_url @@ -208,6 +208,13 @@ def settings_details_POST(owner, name): db.session.commit() return redirect(tracker_url(tracker)) + +def render_tracker_access(tracker, **kwargs): + return render_template("tracker-access.html", + view="access", tracker=tracker, access_type_list=TicketAccess, + access_help_map=access_help_map, **kwargs) + + @tracker.route("///settings/access") @loginrequired def settings_access_GET(owner, name): @@ -216,10 +223,7 @@ def settings_access_GET(owner, name): abort(404) if current_user.id != tracker.owner_id: abort(403) - return render_template("tracker-access.html", - view="access", tracker=tracker, - access_type_list=TicketAccess, - access_help_map=access_help_map) + return render_tracker_access(tracker) @tracker.route("///settings/access", methods=["POST"]) @loginrequired @@ -236,9 +240,7 @@ def settings_access_POST(owner, name): perm_submit = parse_html_perms('submit', valid) if not valid.ok: - return render_template("tracker-access.html", - tracker=tracker, access_type_list=TicketAccess, - access_help_map=access_help_map, **valid.kwargs), 400 + return render_tracker_access(tracker, **valid.kwargs), 400 tracker.default_anonymous_perms = perm_anon tracker.default_user_perms = perm_user @@ -251,6 +253,61 @@ def settings_access_POST(owner, name): db.session.commit() return redirect(tracker_url(tracker)) +@tracker.route("///settings/user-access/create", methods=["POST"]) +@loginrequired +def settings_user_access_create_POST(owner, name): + tracker, access = get_tracker(owner, name) + if not tracker: + abort(404) + if current_user.id != tracker.owner_id: + abort(403) + + valid = Validation(request) + username = valid.require("username") + permissions = parse_html_perms("user_access", valid) + if not valid.ok: + return render_tracker_access(tracker, **valid.kwargs), 400 + + username = username.lstrip("~") + user = User.query.filter_by(username=username).one_or_none() + valid.expect(user, "User not found.", field="username") + if not valid.ok: + return render_tracker_access(tracker, **valid.kwargs), 400 + + existing = UserAccess.query.filter_by(user=user, tracker=tracker).count() + + valid.expect(user != tracker.owner, + "Cannot override tracker owner's permissions.", field="username") + valid.expect(existing == 0, + "This user already has custom permissions assigned.", field="username") + if not valid.ok: + return render_tracker_access(tracker, **valid.kwargs), 400 + + ua = UserAccess(tracker=tracker, user=user, permissions=permissions) + db.session.add(ua) + db.session.commit() + + return redirect(url_for("tracker.settings_access_GET", + owner=tracker.owner.canonical_name, + name=name)) + +@tracker.route("///settings/user-access//delete", + methods=["POST"]) +@loginrequired +def settings_user_access_delete_POST(owner, name, user_id): + tracker, access = get_tracker(owner, name) + if not tracker: + abort(404) + if current_user.id != tracker.owner_id: + abort(403) + + UserAccess.query.filter_by(user_id=user_id, tracker_id=tracker.id).delete() + db.session.commit() + + return redirect(url_for("tracker.settings_access_GET", + owner=tracker.owner.canonical_name, + name=name)) + @tracker.route("///settings/delete") @loginrequired def settings_delete_GET(owner, name): diff --git a/todosrht/templates/tracker-access.html b/todosrht/templates/tracker-access.html index 4db63b7..4329942 100644 --- a/todosrht/templates/tracker-access.html +++ b/todosrht/templates/tracker-access.html @@ -87,6 +87,94 @@ + +
+ +

User permissions

+ +

Here you may override permissions for specific users.

+ + {% if tracker.user_accesses %} + + + {% for user_access in tracker.user_accesses %} + + + + + + + {% endfor %} + +
{{ user_access.user }} + {% if user_access.permissions.name in ["all", "none"] %} + {{ user_access.permissions.name }} + {% else %} + {% for type in access_type_list + if type and type in user_access.permissions %} + {{ type.name }}{% if not loop.last %},{% endif %} + {% endfor %} + {% endif %} + {{ user_access.created|date }} +
+ {{ csrf_token() }} + +
+
+ {% endif %} + +
+ {{ csrf_token() }} + +
+
+

Add user permissions

+ +
+ + + {{ valid.summary("username") }} +
+ +

Permissions

+ +
+ {% for a in access_type_list %} + {{ perm_checkbox(a, TicketAccess.all, "user_access") }} + {% endfor %} + {{ valid.summary("user_access") }} +
+
+
+ + + + +
{% endblock %} diff --git a/todosrht/types/useraccess.py b/todosrht/types/useraccess.py index eea71bd..d29141c 100644 --- a/todosrht/types/useraccess.py +++ b/todosrht/types/useraccess.py @@ -13,7 +13,8 @@ class UserAccess(Base): tracker_id = sa.Column(sa.Integer, sa.ForeignKey("tracker.id", ondelete="CASCADE"), nullable=False) - tracker = sa.orm.relationship("Tracker") + tracker = sa.orm.relationship("Tracker", + backref=sa.orm.backref("user_accesses")) user_id = sa.Column(sa.Integer, sa.ForeignKey("user.id", ondelete="CASCADE"), nullable=False)