Browse Source

Add extremely minimal ban tool (admin only)

This is very minimal and has some weird aspects, but at least it will
let me be able to ban someone from my phone if it's necessary.
merge-requests/65/head
Deimos 6 years ago
parent
commit
888e2763f4
  1. 8
      tildes/tests/test_user.py
  2. 8
      tildes/tildes/models/user/user.py
  3. 1
      tildes/tildes/routes.py
  4. 16
      tildes/tildes/templates/user.jinja2
  5. 24
      tildes/tildes/views/api/web/user.py

8
tildes/tests/test_user.py

@ -134,3 +134,11 @@ def test_banned_user_no_message_permission():
principals = principals_allowed_by_permission(banned_user, "message") principals = principals_allowed_by_permission(banned_user, "message")
assert not principals assert not principals
def test_only_admin_has_ban_permission():
"""Ensure only admins have ban permissions."""
user = User("Test_User", "password")
principals = principals_allowed_by_permission(user, "ban")
assert principals == {"admin"}

8
tildes/tildes/models/user/user.py

@ -198,6 +198,14 @@ class User(DatabaseModel):
acl.append((Deny, self.user_id, "message")) acl.append((Deny, self.user_id, "message"))
acl.append((Allow, Authenticated, "message")) acl.append((Allow, Authenticated, "message"))
# ban:
# - admins can ban non-deleted users except themselves
if self.is_deleted:
acl.append((Deny, Everyone, "ban"))
acl.append((Deny, self.user_id, "ban")) # required so users can't self-ban
acl.append((Allow, "admin", "ban"))
# grant the user all other permissions on themself # grant the user all other permissions on themself
acl.append((Allow, self.user_id, ALL_PERMISSIONS)) acl.append((Allow, self.user_id, ALL_PERMISSIONS))

1
tildes/tildes/routes.py

@ -152,6 +152,7 @@ def add_intercooler_routes(config: Configurator) -> None:
"/default_listing_options", "/default_listing_options",
factory=user_by_username, factory=user_by_username,
) )
add_ic_route("user_ban", "/ban", factory=user_by_username)
class LoggedInFactory: class LoggedInFactory:

16
tildes/tildes/templates/user.jinja2

@ -134,4 +134,20 @@
{% if request.has_permission('message', user) %} {% if request.has_permission('message', user) %}
<a href="/user/{{ user.username }}/new_message" class="btn btn-primary">Send a private message</a> <a href="/user/{{ user.username }}/new_message" class="btn btn-primary">Send a private message</a>
{% endif %} {% endif %}
{% if request.has_permission("ban", user) %}
<div class="divider"></div>
{% if user.is_banned %}
<button class="btn"
data-ic-delete-from="{{ request.route_url("ic_user_ban", username=user.username) }}"
data-ic-confirm="Unban user {{ user.username }}?"
>Unban user</button>
{% else %}
<button class="btn"
data-ic-put-to="{{ request.route_url("ic_user_ban", username=user.username) }}"
data-ic-confirm="Ban user {{ user.username }}?"
>Ban user</button>
{% endif %}
{% endif %}
{% endblock %} {% endblock %}

24
tildes/tildes/views/api/web/user.py

@ -329,3 +329,27 @@ def put_filtered_topic_tags(request: Request, tags: str) -> dict:
request.user.filtered_topic_tags = result.data["tags"] request.user.filtered_topic_tags = result.data["tags"]
return IC_NOOP return IC_NOOP
@ic_view_config(route_name="user_ban", request_method="PUT", permission="ban")
def put_user_ban(request: Request) -> Response:
"""Ban a user."""
user = request.context
user.is_banned = True
# delete all of the user's outstanding invite codes
request.query(UserInviteCode).filter(
UserInviteCode.user_id == user.user_id,
UserInviteCode.invitee_id == None, # noqa
).delete(synchronize_session=False)
return Response("Banned")
@ic_view_config(route_name="user_ban", request_method="DELETE", permission="ban")
def delete_user_ban(request: Request) -> Response:
"""Unban a user."""
request.context.is_banned = False
return Response("Unbanned")
Loading…
Cancel
Save