Merge branch 'main' into minidumps

This commit is contained in:
Klaas van Schelven
2025-11-12 22:15:40 +01:00
9 changed files with 29 additions and 21 deletions

View File

@@ -96,7 +96,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
db: [sqlite, mysql, postgres]
include:
- db: mysql

View File

@@ -107,7 +107,8 @@ class Command(BaseCommand):
return data_bytes
def br_bomb(self, header, size):
filename = "/tmp/br-bomb-%d" % size
# no_bandit_expl utility-script for local consumtion only
filename = "/tmp/br-bomb-%d" % size # nosec B108
if os.path.exists(filename):
with open(filename, "rb") as f:
data_bytes = f.read()
@@ -151,7 +152,7 @@ class Command(BaseCommand):
def zlib_bomb(self, header, size, wbits):
algo = "gzip" if wbits == WBITS_PARAM_FOR_GZIP else "deflate"
filename = "/tmp/%s-bomb-%d" % (algo, size)
filename = "/tmp/%s-bomb-%d" % (algo, size) # nosec B108
if os.path.exists(filename):
with open(filename, "rb") as f:

View File

@@ -91,6 +91,7 @@ def eat_your_own_dogfood(sentry_dsn, **kwargs):
"ee",
"ingest",
"issues",
"files",
"performance",
"phonehome",
"projects",

View File

@@ -149,6 +149,10 @@ LOGGING["handlers"]["snappea"]["level"] = "DEBUG"
LOGGING["loggers"]["snappea"]["level"] = "DEBUG"
LOGGING["formatters"]["snappea"]["format"] = "{asctime} - {threadName} - {levelname:7} - {message}"
# email logger: we mirror the advised logger from #86 here to debug that setting itself as well as get insight in email
# sending during development
LOGGING['loggers']['bugsink.email']['level'] = "INFO"
ALLOWED_HOSTS = deduce_allowed_hosts(BUGSINK["BASE_URL"])
# django-tailwind setting; the below allows for environment-variable overriding of the npm binary path.

View File

@@ -22,6 +22,12 @@ logger = logging.getLogger("bugsink.email")
def send_rendered_email(subject, base_template_name, recipient_list, context=None):
from phonehome.models import Installation
# Clean up; Django will do the same: https://github.com/django/django/blob/main/django/core/mail/message.py#L354
# However, by doing the filter here we avoid logging something that is not reflective of what will actually happen.
recipient_list = [r for r in recipient_list if r]
if not recipient_list:
return
if not Installation.check_and_inc_email_quota(timezone.now()):
logger.warning(
"Email quota exceeded; not sending email with subject '%s' to %s",

View File

@@ -1,12 +1,3 @@
"""
WSGI config for bugsink project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/
"""
import os
import django

View File

@@ -35,28 +35,30 @@ User = get_user_model()
@atomic_for_request_method
def project_list(request, ownership_filter=None):
my_memberships = ProjectMembership.objects.filter(user=request.user)
my_team_memberships = TeamMembership.objects.filter(user=request.user)
# using `id__in` here to ensure the counts later on is not restricted to our own memberships (at most 1)
my_projects = Project.objects.filter(
projectmembership__in=my_memberships, is_deleted=False).order_by('name').distinct()
id__in=ProjectMembership.objects.filter(user=request.user).values('project_id'), is_deleted=False) \
.order_by('name').distinct()
my_teams_projects = \
Project.objects \
.filter(team__teammembership__in=my_team_memberships, is_deleted=False) \
.filter(team_id__in=TeamMembership.objects.filter(user=request.user).values('team_id'), is_deleted=False) \
.exclude(projectmembership__in=my_memberships) \
.order_by('name').distinct()
if request.user.is_superuser:
# superusers can see all project, even hidden ones
# superusers can see all projects, even hidden ones
other_projects = Project.objects \
.filter(is_deleted=False) \
.exclude(projectmembership__in=my_memberships) \
.exclude(team__teammembership__in=my_team_memberships) \
.exclude(id__in=ProjectMembership.objects.filter(user=request.user).values('project_id')) \
.exclude(team_id__in=TeamMembership.objects.filter(user=request.user).values('team_id')) \
.order_by('name').distinct()
else:
other_projects = Project.objects \
.filter(is_deleted=False) \
.exclude(projectmembership__in=my_memberships) \
.exclude(team__teammembership__in=my_team_memberships) \
.exclude(id__in=ProjectMembership.objects.filter(user=request.user).values('project_id')) \
.exclude(team_id__in=TeamMembership.objects.filter(user=request.user).values('team_id')) \
.exclude(visibility=ProjectVisibility.TEAM_MEMBERS) \
.order_by('name').distinct()

View File

@@ -20,6 +20,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dynamic = ["version", "dependencies"]

View File

@@ -25,7 +25,9 @@ User = get_user_model()
@atomic_for_request_method
def team_list(request, ownership_filter=None):
my_memberships = TeamMembership.objects.filter(user=request.user)
my_teams = Team.objects.filter(teammembership__in=my_memberships)
# using `id__in` here to ensure the member_count later on is not restricted to our own memberships (at most 1)
my_teams = Team.objects.filter(id__in=TeamMembership.objects.filter(user=request.user).values('team_id'))
if request.user.is_superuser:
# superusers can see all teams, even hidden ones