-
-
Notifications
You must be signed in to change notification settings - Fork 526
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
463 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
misago/conf/migrations/0015_add_merge_concurrent_posts_setting.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Generated by Django 4.2.10 on 2024-12-15 12:07 | ||
|
||
from django.db import migrations | ||
|
||
from ..operations import CreateSetting | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("misago_conf", "0014_add_threads_lists_settings"), | ||
] | ||
|
||
operations = [ | ||
CreateSetting( | ||
setting="merge_concurrent_posts", | ||
python_type="int", | ||
dry_value=20, | ||
), | ||
] |
35 changes: 0 additions & 35 deletions
35
misago/conf/migrations/0015_add_merge_repeaded_postings_setting.py
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Generated by Django 4.2.10 on 2024-12-15 12:07 | ||
|
||
from django.db import migrations | ||
|
||
from ..operations import CreateSetting | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("misago_conf", "0015_add_merge_concurrent_posts_setting"), | ||
] | ||
|
||
operations = [ | ||
CreateSetting( | ||
setting="flood_control", | ||
python_type="int", | ||
dry_value=20, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from django.db.migrations import RunPython | ||
|
||
|
||
class CreateSetting(RunPython): | ||
def __init__( | ||
self, | ||
*, | ||
setting: str, | ||
python_type: str = "string", | ||
dry_value: str | int | None = None, | ||
is_public: bool = False, | ||
): | ||
code = create_setting(setting, python_type, dry_value, is_public) | ||
reverse_code = delete_setting(setting) | ||
super().__init__(code, reverse_code, atomic=False) | ||
|
||
|
||
def create_setting( | ||
setting: str, python_type: str, dry_value: str | int | None, is_public: bool | ||
): | ||
def migration_operation(apps, _): | ||
Setting = apps.get_model("misago_conf", "Setting") | ||
Setting.objects.create( | ||
setting=setting, | ||
python_type=python_type, | ||
dry_value=dry_value, | ||
is_public=is_public, | ||
) | ||
|
||
return migration_operation | ||
|
||
|
||
def delete_setting(setting: str): | ||
def migration_operation(apps, _): | ||
Setting = apps.get_model("misago_conf", "Setting") | ||
Setting.objects.filter(setting=setting).delete() | ||
|
||
return migration_operation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from datetime import timedelta | ||
|
||
from django.http import HttpRequest | ||
from django.core.exceptions import ValidationError | ||
from django.utils import timezone | ||
from django.utils.translation import pgettext_lazy | ||
|
||
|
||
def flood_control(request: HttpRequest) -> None: | ||
if not request.settings.flood_control: | ||
return | ||
|
||
if request.user_permissions.exempt_from_flood_control: | ||
return | ||
|
||
flood_posts = timezone.now() - timedelta(seconds=request.settings.flood_control) | ||
posts_queryset = request.user.post_set.filter(posted_on__gt=flood_posts) | ||
|
||
if posts_queryset.exists(): | ||
raise ValidationError( | ||
message=pgettext_lazy( | ||
"flood control", | ||
"You can't post a new message so soon after the previous one.", | ||
), | ||
code="flood_control", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from datetime import timedelta | ||
|
||
import pytest | ||
from django.core.exceptions import ValidationError | ||
|
||
from ...conf.test import override_dynamic_settings | ||
from ..floodcontrol import flood_control | ||
|
||
|
||
def test_flood_control_passes_user_without_posts(user_request): | ||
flood_control(user_request) | ||
|
||
|
||
@override_dynamic_settings(flood_control=0) | ||
def test_flood_control_passes_user_if_flood_control_is_disabled( | ||
user_request, user_reply | ||
): | ||
flood_control(user_request) | ||
|
||
|
||
def test_flood_control_fails_user_if_they_have_recent_post(user_request, user_reply): | ||
with pytest.raises(ValidationError) as exc_info: | ||
flood_control(user_request) | ||
|
||
assert exc_info.value.message == ( | ||
"You can't post a new message so soon after the previous one." | ||
) | ||
assert exc_info.value.code == "flood_control" | ||
|
||
|
||
def test_flood_control_passes_user_if_their_last_post_is_old(user_request, user_reply): | ||
user_reply.posted_on -= timedelta(hours=1) | ||
user_reply.save() | ||
|
||
flood_control(user_request) | ||
|
||
|
||
def test_flood_control_passes_user_if_they_are_exempt_from_flood_control( | ||
user_request, user_reply, members_group | ||
): | ||
members_group.exempt_from_flood_control = True | ||
members_group.save() | ||
|
||
flood_control(user_request) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from django.core.exceptions import ValidationError | ||
|
||
from ..formsets import get_start_thread_formset | ||
from ..state import StartThreadState | ||
from ..validators import validate_flood_control | ||
|
||
|
||
def test_validate_flood_control_passes_user_without_posts( | ||
user_request, default_category | ||
): | ||
formset = get_start_thread_formset(user_request, default_category) | ||
state = StartThreadState(user_request, default_category) | ||
|
||
assert validate_flood_control(formset, state) | ||
|
||
|
||
def test_validate_flood_control_fails_user_on_flood_control( | ||
user_request, default_category, user_reply | ||
): | ||
formset = get_start_thread_formset(user_request, default_category) | ||
state = StartThreadState(user_request, default_category) | ||
|
||
assert not validate_flood_control(formset, state) | ||
|
||
error = formset.errors[0] | ||
assert isinstance(error, ValidationError) | ||
assert error.message == ( | ||
"You can't post a new message so soon after the previous one." | ||
) | ||
assert error.code == "flood_control" |
Oops, something went wrong.