diff --git a/accounts/signals.py b/accounts/signals.py index d9440fee..ce1c6fe8 100644 --- a/accounts/signals.py +++ b/accounts/signals.py @@ -4,8 +4,8 @@ from django.contrib.auth.models import Group from django.db import transaction from django.core.files import File from django.core.files.temp import NamedTemporaryFile -import requests from .models import User, UserProfile, EmailVerification +from security import safe_requests @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): @@ -31,7 +31,7 @@ def create_user_profile(sender, instance, created, **kwargs): if avatar_url: try: - response = requests.get(avatar_url, timeout=60) + response = safe_requests.get(avatar_url, timeout=60) if response.status_code == 200: img_temp = NamedTemporaryFile(delete=True) img_temp.write(response.content) diff --git a/location/views.py b/location/views.py index 34ba1d4f..707d64a5 100644 --- a/location/views.py +++ b/location/views.py @@ -12,6 +12,7 @@ from django.db.models import Q from location.forms import LocationForm from .models import Location +from security import safe_requests class LocationSearchView(View): """ @@ -51,7 +52,7 @@ class LocationSearchView(View): elif filter_type == 'city': params['featuretype'] = 'city' - response = requests.get( + response = safe_requests.get( 'https://nominatim.openstreetmap.org/search', params=params, headers={'User-Agent': 'ThrillWiki/1.0'}, @@ -164,7 +165,7 @@ def reverse_geocode(request): return JsonResponse(cached_result) try: - response = requests.get( + response = safe_requests.get( 'https://nominatim.openstreetmap.org/reverse', params={ 'lat': lat, diff --git a/media/management/commands/download_photos.py b/media/management/commands/download_photos.py index 9309f7e8..b11d4b45 100644 --- a/media/management/commands/download_photos.py +++ b/media/management/commands/download_photos.py @@ -1,5 +1,4 @@ import os -import requests from django.core.management.base import BaseCommand from django.core.files import File from django.core.files.temp import NamedTemporaryFile @@ -9,6 +8,7 @@ from rides.models import Ride from django.contrib.contenttypes.models import ContentType import json from django.core.files.base import ContentFile +from security import safe_requests class Command(BaseCommand): help = 'Download photos from seed data URLs' @@ -33,7 +33,7 @@ class Command(BaseCommand): try: # Download image self.stdout.write(f'Downloading from URL: {photo_url}') - response = requests.get(photo_url, timeout=60) + response = safe_requests.get(photo_url, timeout=60) if response.status_code == 200: # Delete any existing photos for this park Photo.objects.filter( @@ -74,7 +74,7 @@ class Command(BaseCommand): try: # Download image self.stdout.write(f'Downloading from URL: {photo_url}') - response = requests.get(photo_url, timeout=60) + response = safe_requests.get(photo_url, timeout=60) if response.status_code == 200: # Delete any existing photos for this ride Photo.objects.filter( diff --git a/parks/management/commands/seed_data.py b/parks/management/commands/seed_data.py index cb8fe520..a89d0fd8 100644 --- a/parks/management/commands/seed_data.py +++ b/parks/management/commands/seed_data.py @@ -6,7 +6,6 @@ from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.core.files.temp import NamedTemporaryFile from django.core.files import File -import requests from parks.models import Park from rides.models import Ride, RollerCoasterStats from companies.models import Company, Manufacturer @@ -15,6 +14,7 @@ from media.models import Photo from django.contrib.auth.models import Permission from datetime import datetime, timedelta import secrets +from security import safe_requests User = get_user_model() @@ -189,7 +189,7 @@ class Command(BaseCommand): def download_image(self, url): """Download image from URL and return as Django File object""" - response = requests.get(url, timeout=60) + response = safe_requests.get(url, timeout=60) if response.status_code == 200: img_temp = NamedTemporaryFile(delete=True) img_temp.write(response.content) diff --git a/parks/views.py b/parks/views.py index a0c4e148..2ca1ccbf 100644 --- a/parks/views.py +++ b/parks/views.py @@ -19,9 +19,9 @@ from django.urls import reverse from django.shortcuts import get_object_or_404, render from decimal import InvalidOperation from django.views.generic import DetailView, ListView, CreateView, UpdateView -import requests from decimal import Decimal, ROUND_DOWN from typing import Any, Optional, cast, Literal +from security import safe_requests # Constants PARK_DETAIL_URL = "parks:park_detail" @@ -140,7 +140,7 @@ def location_search(request: HttpRequest) -> JsonResponse: if not query: return JsonResponse({"results": []}) - response = requests.get( + response = safe_requests.get( "https://nominatim.openstreetmap.org/search", params={ "q": query, @@ -186,7 +186,7 @@ def reverse_geocode(request: HttpRequest) -> JsonResponse: if lon < -180 or lon > 180: return JsonResponse({"error": "Longitude must be between -180 and 180"}, status=400) - response = requests.get( + response = safe_requests.get( "https://nominatim.openstreetmap.org/reverse", params={ "lat": str(lat), diff --git a/pyproject.toml b/pyproject.toml index a62afe69..0c3dbc72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ python = "^3.11" Django = "^5.0" djangorestframework = "^3.14.0" django-cors-headers = "^4.3.1" +security = "==1.3.1" [tool.poetry.dev-dependencies] black = "^25.1.0"