aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps
diff options
context:
space:
mode:
Diffstat (limited to 'pydis_site/apps')
-rw-r--r--pydis_site/apps/api/migrations/0070_new_filter_schema.py28
-rw-r--r--pydis_site/apps/api/migrations/0075_prepare_filter_and_filterlist_for_new_filter_schema.py17
-rw-r--r--pydis_site/apps/api/migrations/0078_merge_20211218_2200.py14
-rw-r--r--pydis_site/apps/api/migrations/0079_add_server_message_and_alert_fields.py69
-rw-r--r--pydis_site/apps/api/models/bot/filters.py44
-rw-r--r--pydis_site/apps/api/serializers.py19
-rw-r--r--pydis_site/apps/api/viewsets/bot/filters.py104
7 files changed, 234 insertions, 61 deletions
diff --git a/pydis_site/apps/api/migrations/0070_new_filter_schema.py b/pydis_site/apps/api/migrations/0070_new_filter_schema.py
index 8716cbad..f56c29f8 100644
--- a/pydis_site/apps/api/migrations/0070_new_filter_schema.py
+++ b/pydis_site/apps/api/migrations/0070_new_filter_schema.py
@@ -1,4 +1,5 @@
# Modified migration file to migrate existing filters to the new one
+from datetime import timedelta
import django.contrib.postgres.fields
from django.apps.registry import Apps
@@ -18,20 +19,27 @@ def forward(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
for name, type_ in OLD_LIST_NAMES:
objects = filter_list_old.objects.filter(type=name)
+ if name == "DOMAIN_NAME":
+ dm_content = "Your URL has been removed because it matched a blacklisted domain: {match}"
+ elif name == "GUILD_INVITE":
+ dm_content = "Per Rule 6, your invite link has been removed. " \
+ "Our server rules can be found here: https://pythondiscord.com/pages/rules"
+ else:
+ dm_content = ""
list_ = filter_list.objects.create(
name=name.lower(),
list_type=1 if type_ == "ALLOW" else 0,
- ping_type=["onduty"],
+ ping_type=(["onduty"] if name != "FILE_FORMAT" else []),
filter_dm=True,
- dm_ping_type=["onduty"],
- delete_messages=True,
- bypass_roles=[267630620367257601],
- enabled=False,
- dm_content=None,
- infraction_type=None,
+ dm_ping_type=[],
+ delete_messages=(True if name != "FILTER_TOKEN" else False),
+ bypass_roles=["staff"],
+ enabled=True,
+ dm_content=dm_content,
+ infraction_type="",
infraction_reason="",
- infraction_duration=None,
+ infraction_duration=timedelta(seconds=0),
disallowed_channels=[],
disallowed_categories=[],
allowed_channels=[],
@@ -84,7 +92,7 @@ class Migration(migrations.Migration):
('filter_dm', models.BooleanField(help_text='Whether DMs should be filtered.', null=True)),
('dm_ping_type', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=20), help_text='Who to ping when this filter triggers on a DM.', size=None, validators=[pydis_site.apps.api.models.bot.filters.validate_ping_field], null=True)),
('delete_messages', models.BooleanField(help_text='Whether this filter should delete messages triggering it.', null=True)),
- ('bypass_roles', django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(), help_text='Roles and users who can bypass this filter.', size=None, null=True)),
+ ('bypass_roles', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), help_text='Roles and users who can bypass this filter.', size=None, validators=[pydis_site.apps.api.models.bot.filters.validate_bypass_roles_field], null=True)),
('enabled', models.BooleanField(help_text='Whether this filter is currently enabled.', null=True)),
('dm_content', models.CharField(help_text='The DM to send to a user triggering this filter.', max_length=1000, null=True)),
('infraction_type', models.CharField(choices=[('note', 'Note'), ('warning', 'Warning'), ('watch', 'Watch'), ('mute', 'Mute'), ('kick', 'Kick'), ('ban', 'Ban'), ('superstar', 'Superstar'), ('voice_ban', 'Voice Ban')], help_text='The infraction to apply to this user.', max_length=9, null=True)),
@@ -106,7 +114,7 @@ class Migration(migrations.Migration):
('filter_dm', models.BooleanField(help_text='Whether DMs should be filtered.')),
('dm_ping_type', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=20), help_text='Who to ping when this filter triggers on a DM.', size=None, validators=[pydis_site.apps.api.models.bot.filters.validate_ping_field])),
('delete_messages', models.BooleanField(help_text='Whether this filter should delete messages triggering it.')),
- ('bypass_roles', django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(), help_text='Roles and users who can bypass this filter.', size=None)),
+ ('bypass_roles', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=100), help_text='Roles and users who can bypass this filter.', size=None, validators=[pydis_site.apps.api.models.bot.filters.validate_bypass_roles_field])),
('enabled', models.BooleanField(help_text='Whether this filter is currently enabled.')),
('dm_content', models.CharField(help_text='The DM to send to a user triggering this filter.', max_length=1000, null=True)),
('infraction_type', models.CharField(choices=[('note', 'Note'), ('warning', 'Warning'), ('watch', 'Watch'), ('mute', 'Mute'), ('kick', 'Kick'), ('ban', 'Ban'), ('superstar', 'Superstar'), ('voice_ban', 'Voice Ban')], help_text='The infraction to apply to this user.', max_length=9, null=True)),
diff --git a/pydis_site/apps/api/migrations/0075_prepare_filter_and_filterlist_for_new_filter_schema.py b/pydis_site/apps/api/migrations/0075_prepare_filter_and_filterlist_for_new_filter_schema.py
index 30537e3d..cc524fcb 100644
--- a/pydis_site/apps/api/migrations/0075_prepare_filter_and_filterlist_for_new_filter_schema.py
+++ b/pydis_site/apps/api/migrations/0075_prepare_filter_and_filterlist_for_new_filter_schema.py
@@ -10,12 +10,26 @@ def migrate_filterlist(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> N
"filter_token": "tokens",
"domain_name": "domains",
"guild_invite": "invites",
- "file_format": "formats"
+ "file_format": "extensions"
}
for filter_list in FilterList.objects.all():
if change_map.get(filter_list.name):
filter_list.name = change_map.get(filter_list.name)
filter_list.save()
+ redirects = FilterList(
+ name="redirects",
+ ping_type=[],
+ dm_ping_type=[],
+ enabled_channels=[],
+ disabled_channels=[],
+ disabled_categories=[],
+ list_type=0,
+ filter_dm=True,
+ delete_messages=False,
+ bypass_roles=[0],
+ enabled=True
+ )
+ redirects.save()
def unmigrate_filterlist(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
@@ -30,6 +44,7 @@ def unmigrate_filterlist(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) ->
if change_map.get(filter_list.name):
filter_list.name = change_map.get(filter_list.name)
filter_list.save()
+ FilterList.objects.filter(name="redirects").delete()
class Migration(migrations.Migration):
diff --git a/pydis_site/apps/api/migrations/0078_merge_20211218_2200.py b/pydis_site/apps/api/migrations/0078_merge_20211218_2200.py
new file mode 100644
index 00000000..7fe559f5
--- /dev/null
+++ b/pydis_site/apps/api/migrations/0078_merge_20211218_2200.py
@@ -0,0 +1,14 @@
+# Generated by Django 3.1.14 on 2021-12-18 22:00
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0075_prepare_filter_and_filterlist_for_new_filter_schema'),
+ ('api', '0077_use_generic_jsonfield'),
+ ]
+
+ operations = [
+ ]
diff --git a/pydis_site/apps/api/migrations/0079_add_server_message_and_alert_fields.py b/pydis_site/apps/api/migrations/0079_add_server_message_and_alert_fields.py
new file mode 100644
index 00000000..f9803bd3
--- /dev/null
+++ b/pydis_site/apps/api/migrations/0079_add_server_message_and_alert_fields.py
@@ -0,0 +1,69 @@
+# Generated by Django 3.1.14 on 2021-12-19 23:05
+from django.apps.registry import Apps
+from django.db import migrations, models
+from django.db.backends.base.schema import BaseDatabaseSchemaEditor
+
+
+def migrate_filterlist(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
+ FilterList = apps.get_model("api", "FilterList")
+ change_map = {
+ "tokens": True,
+ "domains": True,
+ "invites": True,
+ "extensions": False,
+ "redirects": False
+ }
+ for filter_list in FilterList.objects.all():
+ filter_list.send_alert = change_map.get(filter_list.name)
+ filter_list.server_message_text = ""
+ filter_list.server_message_embed = ""
+ filter_list.save()
+
+
+def unmigrate_filterlist(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
+ FilterList = apps.get_model("api", "FilterList")
+ for filter_list in FilterList.objects.all():
+ filter_list.send_alert = True
+ filter_list.server_message_text = None
+ filter_list.server_message_embed = None
+ filter_list.save()
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ('api', '0078_merge_20211218_2200'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='filter',
+ name='send_alert',
+ field=models.BooleanField(help_text='Whether alert should be sent.', null=True),
+ ),
+ migrations.AddField(
+ model_name='filter',
+ name='server_message_embed',
+ field=models.CharField(help_text='The content of the server message embed', max_length=100, null=True),
+ ),
+ migrations.AddField(
+ model_name='filter',
+ name='server_message_text',
+ field=models.CharField(help_text='The message to send on the server', max_length=100, null=True),
+ ),
+ migrations.AddField(
+ model_name='filterlist',
+ name='send_alert',
+ field=models.BooleanField(default=True, help_text='Whether alert should be sent.'),
+ ),
+ migrations.AddField(
+ model_name='filterlist',
+ name='server_message_embed',
+ field=models.CharField(help_text='The content of the server message embed', max_length=100, null=True),
+ ),
+ migrations.AddField(
+ model_name='filterlist',
+ name='server_message_text',
+ field=models.CharField(help_text='The message to send on the server', max_length=100, null=True),
+ ),
+ migrations.RunPython(migrate_filterlist, unmigrate_filterlist)
+ ]
diff --git a/pydis_site/apps/api/models/bot/filters.py b/pydis_site/apps/api/models/bot/filters.py
index ae877685..92251ee4 100644
--- a/pydis_site/apps/api/models/bot/filters.py
+++ b/pydis_site/apps/api/models/bot/filters.py
@@ -18,6 +18,7 @@ class FilterListType(models.IntegerChoices):
# Valid special values in ping related fields
VALID_PINGS = ("everyone", "here", "moderators", "onduty", "admins")
+VALID_BYPASS_ROLES = ("staff",)
def validate_ping_field(value_list: List[str]) -> None:
@@ -33,6 +34,14 @@ def validate_ping_field(value_list: List[str]) -> None:
raise ValidationError(f"{value!r} isn't a valid ping type.")
+def validate_bypass_roles_field(value_list: List[str]) -> None:
+ """Validate that the vclues are either a special value or a Role ID."""
+ for value in value_list:
+ if value.isnumeric() or value in VALID_BYPASS_ROLES:
+ continue
+ raise ValidationError(f"{value!r} isn't a valid (bypass) role.")
+
+
class FilterSettingsMixin(models.Model):
"""Mixin for common settings of a filters and filter lists."""
@@ -88,14 +97,30 @@ class FilterList(FilterSettingsMixin):
null=False
)
bypass_roles = ArrayField(
- models.BigIntegerField(),
+ models.CharField(max_length=100),
help_text="Roles and users who can bypass this filter.",
+ validators=(validate_bypass_roles_field,),
null=False
)
enabled = models.BooleanField(
help_text="Whether this filter is currently enabled.",
null=False
)
+ send_alert = models.BooleanField(
+ help_text="Whether alert should be sent.",
+ null=False,
+ default=True
+ )
+ server_message_text = models.CharField(
+ max_length=100,
+ help_text="The message to send on the server",
+ null=True
+ )
+ server_message_embed = models.CharField(
+ max_length=100,
+ help_text="The content of the server message embed",
+ null=True
+ )
# Where a filter should apply.
#
# The resolution is done in the following order:
@@ -145,14 +170,29 @@ class Filter(FilterSettingsMixin):
null=True
)
bypass_roles = ArrayField(
- models.BigIntegerField(),
+ models.CharField(max_length=100),
help_text="Roles and users who can bypass this filter.",
+ validators=(validate_bypass_roles_field,),
null=True
)
enabled = models.BooleanField(
help_text="Whether this filter is currently enabled.",
null=True
)
+ send_alert = models.BooleanField(
+ help_text="Whether alert should be sent.",
+ null=True
+ )
+ server_message_text = models.CharField(
+ max_length=100,
+ help_text="The message to send on the server",
+ null=True
+ )
+ server_message_embed = models.CharField(
+ max_length=100,
+ help_text="The content of the server message embed",
+ null=True
+ )
# Check FilterList model for information about these properties.
enabled_channels = ArrayField(models.IntegerField(), null=True)
diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py
index 784f8160..30af9512 100644
--- a/pydis_site/apps/api/serializers.py
+++ b/pydis_site/apps/api/serializers.py
@@ -139,7 +139,8 @@ BASE_SETTINGS_FIELDS = (
"bypass_roles",
"filter_dm",
"enabled",
- "delete_messages"
+ "delete_messages",
+ "send_alert"
)
INFRACTION_FIELDS = ("infraction_type", "infraction_reason", "infraction_duration")
CHANNEL_SCOPE_FIELDS = (
@@ -147,6 +148,7 @@ CHANNEL_SCOPE_FIELDS = (
"disabled_categories",
"enabled_channels",
)
+SERVER_MESSAGE_FIELDS = ("server_message_text", "server_message_embed")
MENTIONS_FIELDS = ("ping_type", "dm_ping_type")
SETTINGS_FIELDS = ALWAYS_OPTIONAL_SETTINGS + REQUIRED_FOR_FILTER_LIST_SETTINGS
@@ -214,10 +216,16 @@ class FilterSerializer(ModelSerializer):
"mentions":
{
schema_field_name: getattr(instance, schema_field_name)
- for schema_field_name in MENTIONS_FIELDS}
+ for schema_field_name in MENTIONS_FIELDS
+ }
}
+ } | {
+ "server_message":
+ {
+ schema_field_name: getattr(instance, schema_field_name)
+ for schema_field_name in SERVER_MESSAGE_FIELDS
+ }
}
-
schema_base = {name: getattr(instance, name) for name in BASE_FILTER_FIELDS} | \
{"filter_list": instance.filter_list.id}
@@ -307,6 +315,11 @@ class FilterListSerializer(ModelSerializer):
schema_field_name: getattr(instance, schema_field_name)
for schema_field_name in MENTIONS_FIELDS
}
+ } | {
+ "server_message": {
+ schema_field_name: getattr(instance, schema_field_name)
+ for schema_field_name in SERVER_MESSAGE_FIELDS
+ }
}
return schema_base | {"settings": schema_settings_base | schema_settings_categories}
diff --git a/pydis_site/apps/api/viewsets/bot/filters.py b/pydis_site/apps/api/viewsets/bot/filters.py
index 20af079d..e52cd4e5 100644
--- a/pydis_site/apps/api/viewsets/bot/filters.py
+++ b/pydis_site/apps/api/viewsets/bot/filters.py
@@ -22,20 +22,21 @@ class FilterListViewSet(ModelViewSet):
>>> [
... {
... "id": 1,
- ... "name": "guild_invite",
+ ... "name": "invites",
... "list_type": 1,
... "filters": [
... {
... "id": 1,
- ... "filter_list": 1
... "content": "267624335836053506",
... "description": "Python Discord",
... "additional_field": None,
+ ... "filter_list": 1
... "settings": {
... "bypass_roles": None
... "filter_dm": None,
- ... "enabled": False
- ... "delete_messages": True
+ ... "enabled": None
+ ... "send_alert": True,
+ ... "delete_messages": None
... "infraction": {
... "infraction_type": None,
... "infraction_reason": "",
@@ -50,37 +51,42 @@ class FilterListViewSet(ModelViewSet):
... "ping_type": None
... "dm_ping_type": None
... }
+ ... "server_message": {
+ ... "server_message_text": None,
+ ... "server_message_embed": None
+ ... }
... }
...
... },
... ...
... ],
... "settings": {
- ... "ping_type": [
- ... "onduty"
- ... ],
- ... "dm_ping_type": [
- ... "onduty"
- ... ],
... "bypass_roles": [
- ... 267630620367257601
+ ... "staff"
... ],
... "filter_dm": True,
- ... "enabled": False
- ... "delete_messages": True
+ ... "enabled": True
+ ... "delete_messages": True,
+ ... "send_alert": True
... "infraction": {
- ... "infraction_type": None,
+ ... "infraction_type": "",
... "infraction_reason": "",
- ... "infraction_duration": None,
+ ... "infraction_duration": "0.0",
... }
... "channel_scope": {
- ... "disabled_channels": None,
- ... "disabled_categories": None,
- ... "enabled_channels": None
- ... }
+ ... "disabled_channels": [],
+ ... "disabled_categories": [],
+ ... "enabled_channels": []
+ ... }
... "mentions": {
- ... "ping_type": None
- ... "dm_ping_type": None
+ ... "ping_type": [
+ ... "onduty"
+ ... ]
+ ... "dm_ping_type": []
+ ... }
+ ... "server_message": {
+ ... "server_message_text": "",
+ ... "server_message_embed": ""
... }
... },
... ...
@@ -96,7 +102,7 @@ class FilterListViewSet(ModelViewSet):
#### Response format
>>> {
... "id": 1,
- ... "name": "guild_invite",
+ ... "name": "invites",
... "list_type": 1,
... "filters": [
... {
@@ -108,8 +114,9 @@ class FilterListViewSet(ModelViewSet):
... "settings": {
... "bypass_roles": None
... "filter_dm": None,
- ... "enabled": False
- ... "delete_messages": True
+ ... "enabled": None
+ ... "delete_messages": None,
+ ... "send_alert": None
... "infraction": {
... "infraction_type": None,
... "infraction_reason": "",
@@ -124,37 +131,42 @@ class FilterListViewSet(ModelViewSet):
... "ping_type": None
... "dm_ping_type": None
... }
+ ... "server_message": {
+ ... "server_message_text": None,
+ ... "server_message_embed": None
+ ... }
... }
...
... },
... ...
... ],
... "settings": {
- ... "ping_type": [
- ... "onduty"
- ... ],
- ... "dm_ping_type": [
- ... "onduty"
- ... ],
... "bypass_roles": [
- ... 267630620367257601
+ ... "staff"
... ],
... "filter_dm": True,
- ... "enabled": False
+ ... "enabled": True
... "delete_messages": True
+ ... "send_alert": True
... "infraction": {
- ... "infraction_type": None,
+ ... "infraction_type": "",
... "infraction_reason": "",
- ... "infraction_duration": None,
+ ... "infraction_duration": "0.0",
... }
... "channel_scope": {
- ... "disabled_channels": None,
- ... "disabled_categories": None,
- ... "enabled_channels": None
+ ... "disabled_channels": [],
+ ... "disabled_categories": [],
+ ... "enabled_channels": []
... }
... "mentions": {
- ... "ping_type": None
- ... "dm_ping_type": None
+ ... "ping_type": [
+ ... "onduty"
+ ... ]
+ ... "dm_ping_type": []
+ ... }
+ ... "server_message": {
+ ... "server_message_text": "",
+ ... "server_message_embed": ""
... }
... }
@@ -193,11 +205,12 @@ class FilterViewSet(ModelViewSet):
... "settings": {
... "bypass_roles": None
... "filter_dm": None,
- ... "enabled": False
- ... "delete_messages": True
+ ... "enabled": None
+ ... "delete_messages": True,
+ ... "send_alert": True
... "infraction": {
... "infraction_type": None,
- ... "infraction_reason": "",
+ ... "infraction_reason": None,
... "infraction_duration": None
... },
... "channel_scope": {
@@ -231,11 +244,12 @@ class FilterViewSet(ModelViewSet):
... "settings": {
... "bypass_roles": None
... "filter_dm": None,
- ... "enabled": False
- ... "delete_messages": True
+ ... "enabled": None
+ ... "delete_messages": True,
+ ... "send_alert": True
... "infraction": {
... "infraction_type": None,
- ... "infraction_reason": "",
+ ... "infraction_reason": None,
... "infraction_duration": None
... },
... "channel_scope": {