Browse Source

Disallow a user from banning themselves.

Closes tildes-community/tildes-cf#9

See merge request tildes-community/tildes-cf!12
develop
Bauke 3 weeks ago
committed by Andrew Shu
parent
commit
cdb15cc0d0
  1. 36
      tildes/tests/conftest.py
  2. 18
      tildes/tests/webtests/test_admin_user.py
  3. 2
      tildes/tildes/templates/user.jinja2
  4. 4
      tildes/tildes/views/api/web/user.py

36
tildes/tests/conftest.py

@ -15,8 +15,9 @@ from testing.redis import RedisServer
from webtest import TestApp from webtest import TestApp
from scripts.initialize_db import create_tables from scripts.initialize_db import create_tables
from tildes.enums import UserPermission
from tildes.models.group import Group from tildes.models.group import Group
from tildes.models.user import User
from tildes.models.user import User, UserPermissions
# include the fixtures defined in fixtures.py # include the fixtures defined in fixtures.py
@ -172,6 +173,25 @@ def session_user2(sdb):
yield user yield user
@fixture(scope="session", autouse=True)
def session_admin_user(sdb):
"""Create a third user named 'AdminUser' in the db for test session.
This user is granted all available user permissions.
"""
user = User("AdminUser", "admin user password")
for permission in UserPermission:
user_permission = UserPermissions()
user_permission.user = user
user_permission.permission = permission
sdb.add(user_permission)
sdb.add(user)
sdb.commit()
yield user
@fixture(scope="session", autouse=True) @fixture(scope="session", autouse=True)
def session_group(sdb): def session_group(sdb):
"""Create a group named 'sessiongroup' in the db for test session.""" """Create a group named 'sessiongroup' in the db for test session."""
@ -220,6 +240,20 @@ def webtest(base_app):
yield app yield app
@fixture(scope="session")
def webtest_admin(base_app):
"""Create a webtest TestApp and log in as the AdminUser account in it."""
app = TestApp(base_app, extra_environ=WEBTEST_EXTRA_ENVIRON)
# fetch the login page, fill in the form, and submit it (sets the cookie)
login_page = app.get("/login")
login_page.form["username"] = "AdminUser"
login_page.form["password"] = "admin user password"
login_page.form.submit()
yield app
@fixture(scope="function") @fixture(scope="function")
def webtest_loggedout(base_app): def webtest_loggedout(base_app):
"""Create a logged-out webtest TestApp (function scope, so no state is retained).""" """Create a logged-out webtest TestApp (function scope, so no state is retained)."""

18
tildes/tests/webtests/test_admin_user.py

@ -0,0 +1,18 @@
# Copyright (c) 2025 Tildes contributors <code@tildes.net>
# SPDX-License-Identifier: AGPL-3.0-or-later
def test_ban_button_hidden_from_self(webtest_admin):
"""Test that the Ban button is hidden on a user's own profile."""
profile = webtest_admin.get("/user/AdminUser")
assert profile.status_int == 200
assert profile.text.count("Ban user") == 0
assert profile.text.count("Unban user") == 0
def test_ban_button_shown_for_other_user(webtest_admin):
"""Test that the Ban button is shown on a different user's profile."""
profile = webtest_admin.get("/user/SessionUser")
assert profile.status_int == 200
assert profile.text.count("Ban user") > 0
assert profile.text.count("Unban user") == 0

2
tildes/tildes/templates/user.jinja2

@ -189,7 +189,7 @@
<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) %}
{% if request.user != user and request.has_permission("ban", user) %}
<div class="divider"></div> <div class="divider"></div>
{% if user.is_banned %} {% if user.is_banned %}
<button class="btn" <button class="btn"

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

@ -10,6 +10,7 @@ from typing import Optional
from marshmallow import ValidationError from marshmallow import ValidationError
from marshmallow.fields import String from marshmallow.fields import String
from pyramid.httpexceptions import ( from pyramid.httpexceptions import (
HTTPBadRequest,
HTTPForbidden, HTTPForbidden,
HTTPUnauthorized, HTTPUnauthorized,
HTTPUnprocessableEntity, HTTPUnprocessableEntity,
@ -406,6 +407,9 @@ def put_user_ban(request: Request) -> Response:
"""Ban a user.""" """Ban a user."""
user = request.context user = request.context
if request.user == user:
raise HTTPBadRequest("You cannot ban yourself")
user.is_banned = True user.is_banned = True
# delete all of the user's outstanding invite codes # delete all of the user's outstanding invite codes

Loading…
Cancel
Save