05/06 Fix some notable and quality issues
This commit is contained in:
+27
-1
@@ -1,6 +1,32 @@
|
||||
from functools import wraps
|
||||
from flask import flash, redirect, url_for
|
||||
from flask import flash, redirect, url_for, request
|
||||
from flask_login import current_user
|
||||
from urllib.parse import urlparse
|
||||
|
||||
|
||||
# ── Open-redirect guard ───────────────────────────────────────────────────────
|
||||
|
||||
def safe_redirect_url(url: str | None, fallback: str | None = None) -> str:
|
||||
"""Return *url* only if it is a safe relative URL on this host.
|
||||
|
||||
Rejects any URL that carries a network location (netloc) or an explicit
|
||||
scheme, preventing open-redirect attacks where a crafted link contains
|
||||
next=https://evil.com.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
url : The candidate redirect target (may be None).
|
||||
fallback : Returned when *url* is absent or unsafe.
|
||||
Defaults to the dashboard index.
|
||||
"""
|
||||
if fallback is None:
|
||||
fallback = url_for('dashboard.index')
|
||||
if not url:
|
||||
return fallback
|
||||
parsed = urlparse(url)
|
||||
if parsed.netloc or parsed.scheme:
|
||||
return fallback
|
||||
return url
|
||||
|
||||
def admin_required(f):
|
||||
@wraps(f)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
from flask_wtf import FlaskForm
|
||||
from flask_wtf.file import FileField, FileAllowed
|
||||
from flask_wtf.file import FileField, FileAllowed, MultipleFileField
|
||||
from wtforms import (StringField, PasswordField, SelectField, TextAreaField,
|
||||
DecimalField, BooleanField, IntegerField, HiddenField,
|
||||
RadioField)
|
||||
@@ -174,7 +174,7 @@ class IssueUpdateForm(FlaskForm):
|
||||
assigned_to = SelectField('Assign To', coerce=int, validators=[Optional()])
|
||||
update_notes = TextAreaField('Update Notes', validators=[Optional(), Length(max=1000)])
|
||||
result_notes = TextAreaField('Result Notes', validators=[Optional(), Length(max=2000)])
|
||||
result_photos = FileField('Result Photos', validators=[
|
||||
result_photos = MultipleFileField('Result Photos', validators=[
|
||||
Optional(),
|
||||
FileAllowed(['jpg','jpeg','png','gif'], 'Images only.')
|
||||
])
|
||||
|
||||
+4
-1
@@ -110,9 +110,12 @@ def send_sla_alerts():
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# yield_per streams rows in batches of 100 rather than loading all open
|
||||
# issues into memory at once. At current scale this is a no-op difference,
|
||||
# but it prevents a memory spike if the issue count grows large.
|
||||
open_issues = Issue.query.filter(
|
||||
Issue.status.in_(['open', 'in_progress', 'pending_verification'])
|
||||
).all()
|
||||
).yield_per(100)
|
||||
|
||||
total_sent = 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user