Browse Source

refactor(api): replace build_absolute_uri with absolute_https_url

Replace direct calls to `request.build_absolute_uri` with a centralized
`absolute_https_url` utility across account and hadis modules. This
ensures consistent enforcement of HTTPS for all absolute media URLs
(avatars, thumbnails, and images) in serializers and views.rl
master
mortezaei 2 weeks ago
parent
commit
4be852ff41
  1. 8
      apps/account/views/user.py
  2. 17
      apps/hadis/serializers/hadis.py
  3. 19
      apps/hadis/serializers/reference_v2.py
  4. 6
      apps/hadis/serializers/serializers_admin.py
  5. 3
      apps/hadis/views/category.py

8
apps/account/views/user.py

@ -27,7 +27,7 @@ from apps.account.serializers import UserRegisterSerializer, UserProfileSerializ
from apps.account.serializers.user_web import WebUserRegisterSerializer from apps.account.serializers.user_web import WebUserRegisterSerializer
from utils.redis import RedisManager from utils.redis import RedisManager
from utils.exceptions import AppAPIException from utils.exceptions import AppAPIException
from utils import send_email, is_valid_email
from utils import send_email, is_valid_email, absolute_https_url
from config.settings import base as settings from config.settings import base as settings
from apps.account.permissions import IsActiveUser, IsSuperAdminOrReadOnlyForProfessor from apps.account.permissions import IsActiveUser, IsSuperAdminOrReadOnlyForProfessor
from apps.account.doc import * from apps.account.doc import *
@ -431,7 +431,7 @@ class UserLoginView(CreateAPIView):
"email": user.email, "email": user.email,
"token": token.key, "token": token.key,
"user_type": user.user_type, "user_type": user.user_type,
"avatar": request.build_absolute_uri(user.avatar.url) if user.avatar else None,
"avatar": absolute_https_url(user.avatar.url, request) if user.avatar else None,
}, status=status.HTTP_201_CREATED) }, status=status.HTTP_201_CREATED)
@ -492,7 +492,7 @@ class UserRecoverPassword(CreateAPIView):
"fullname": user.fullname, "fullname": user.fullname,
"phone_number": str(user.phone_number) if user.phone_number else None, "phone_number": str(user.phone_number) if user.phone_number else None,
"email": user.email if user.email else None, "email": user.email if user.email else None,
"avatar": request.build_absolute_uri(user.avatar.url) if user.avatar else None,
"avatar": absolute_https_url(user.avatar.url, request) if user.avatar else None,
"message": "Forgot password code sent" "message": "Forgot password code sent"
}, },
status=status.HTTP_202_ACCEPTED, status=status.HTTP_202_ACCEPTED,
@ -633,7 +633,7 @@ class AdminLoginView(CreateAPIView):
"email": user.email, "email": user.email,
"token": token.key, "token": token.key,
"user_type": effective_user_type, "user_type": effective_user_type,
"avatar": request.build_absolute_uri(user.avatar.url) if user.avatar else None,
"avatar": absolute_https_url(user.avatar.url, request) if user.avatar else None,
}, status=status.HTTP_201_CREATED) }, status=status.HTTP_201_CREATED)

17
apps/hadis/serializers/hadis.py

@ -8,6 +8,7 @@ from .category import LocalizedField, ArabicLocalizedField
from .category import get_localized_text, get_arabic_localized_text from .category import get_localized_text, get_arabic_localized_text
from .category import get_localized_text from .category import get_localized_text
from apps.bookmark.serializers.bookmark import BookmarkStatusSerializer from apps.bookmark.serializers.bookmark import BookmarkStatusSerializer
from utils import absolute_https_url
from ..models import ( from ..models import (
Hadis, HadisStatus, HadisTag, HadisTransmitter, Hadis, HadisStatus, HadisTag, HadisTransmitter,
@ -58,8 +59,8 @@ class PinnedHadisCollectionSerializer(serializers.ModelSerializer):
if obj.thumbnail: if obj.thumbnail:
request = self.context.get('request') request = self.context.get('request')
if request: if request:
return request.build_absolute_uri(obj.thumbnail.url)
return obj.thumbnail.url
return absolute_https_url(obj.thumbnail.url, request)
return absolute_https_url(obj.thumbnail.url)
return None return None
class HadisCollectionListSerializer(serializers.ModelSerializer): class HadisCollectionListSerializer(serializers.ModelSerializer):
@ -75,8 +76,8 @@ class HadisCollectionListSerializer(serializers.ModelSerializer):
if obj.thumbnail: if obj.thumbnail:
request = self.context.get('request') request = self.context.get('request')
if request: if request:
return request.build_absolute_uri(obj.thumbnail.url)
return obj.thumbnail.url
return absolute_https_url(obj.thumbnail.url, request)
return absolute_https_url(obj.thumbnail.url)
return None return None
@ -142,7 +143,7 @@ class HadisSyncSerializer(serializers.ModelSerializer):
for img in reference.images.all(): for img in reference.images.all():
thumb_url = None thumb_url = None
if img.thumbnail: if img.thumbnail:
thumb_url = request.build_absolute_uri(img.thumbnail.url) if request else img.thumbnail.url
thumb_url = absolute_https_url(img.thumbnail.url, request)
reference_images_block.append({ reference_images_block.append({
'id': img.id, 'id': img.id,
'thumbnail': thumb_url, 'thumbnail': thumb_url,
@ -770,8 +771,8 @@ class ReferenceImageSerializer(serializers.ModelSerializer):
if obj.thumbnail: if obj.thumbnail:
request = self.context.get('request') request = self.context.get('request')
if request: if request:
return request.build_absolute_uri(obj.thumbnail.url)
return obj.thumbnail.url
return absolute_https_url(obj.thumbnail.url, request)
return absolute_https_url(obj.thumbnail.url)
return None return None
@ -1220,4 +1221,4 @@ class TransmitterOriginalTextDetailSerializer(serializers.ModelSerializer):
"id": obj.transmitter.id, "id": obj.transmitter.id,
"slug": obj.transmitter.slug, "slug": obj.transmitter.slug,
"name": get_localized_text(obj.transmitter.full_name, self.context.get('request')) "name": get_localized_text(obj.transmitter.full_name, self.context.get('request'))
}
}

19
apps/hadis/serializers/reference_v2.py

@ -5,6 +5,7 @@ from .category import get_localized_text
from apps.hadis.serializers import HadisListSerializer, HadisShortSerializer from apps.hadis.serializers import HadisListSerializer, HadisShortSerializer
from ..serializers.category import LocalizedField from ..serializers.category import LocalizedField
from ..serializers.reference import BookAttributeSerializer, BookReferenceImageSerializer from ..serializers.reference import BookAttributeSerializer, BookReferenceImageSerializer
from utils import absolute_https_url
class BookTagV2Serializer(serializers.ModelSerializer): class BookTagV2Serializer(serializers.ModelSerializer):
title = LocalizedField() title = LocalizedField()
@ -58,8 +59,8 @@ class BookReferenceV2ListSerializer(serializers.ModelSerializer):
if first_image and first_image.image: if first_image and first_image.image:
request = self.context.get('request') request = self.context.get('request')
if request: if request:
return request.build_absolute_uri(first_image.image.url)
return first_image.image.url
return absolute_https_url(first_image.image.url, request)
return absolute_https_url(first_image.image.url)
return None return None
class BookEditionV2Serializer(serializers.ModelSerializer): class BookEditionV2Serializer(serializers.ModelSerializer):
@ -99,8 +100,8 @@ class BookVolumeV2Serializer(serializers.ModelSerializer):
if first_image and first_image.image: if first_image and first_image.image:
request = self.context.get('request') request = self.context.get('request')
if request: if request:
return request.build_absolute_uri(first_image.image.url)
return first_image.image.url
return absolute_https_url(first_image.image.url, request)
return absolute_https_url(first_image.image.url)
return None return None
class BookReferenceV2DetailSerializer(serializers.ModelSerializer): class BookReferenceV2DetailSerializer(serializers.ModelSerializer):
@ -128,8 +129,8 @@ class BookReferenceV2DetailSerializer(serializers.ModelSerializer):
if first_image and first_image.image: if first_image and first_image.image:
request = self.context.get('request') request = self.context.get('request')
if request: if request:
return request.build_absolute_uri(first_image.image.url)
return first_image.image.url
return absolute_https_url(first_image.image.url, request)
return absolute_https_url(first_image.image.url)
return None return None
def get_information(self, obj): def get_information(self, obj):
@ -305,8 +306,8 @@ class AuthorBookReferenceSerializer(serializers.ModelSerializer):
if first_image and first_image.image: if first_image and first_image.image:
request = self.context.get('request') request = self.context.get('request')
if request: if request:
return request.build_absolute_uri(first_image.image.url)
return first_image.image.url
return absolute_https_url(first_image.image.url, request)
return absolute_https_url(first_image.image.url)
return None return None
# یک سریالایزر مینیمال برای کتاب‌ها داخل سینک # یک سریالایزر مینیمال برای کتاب‌ها داخل سینک
@ -350,4 +351,4 @@ class BookAuthorSyncSerializer(serializers.ModelSerializer):
'death_year_miladi', 'death_year_miladi',
'books', # 👈 لیست کتاب‌های هر نویسنده 'books', # 👈 لیست کتاب‌های هر نویسنده
'related_narrator_slug' 'related_narrator_slug'
]
]

6
apps/hadis/serializers/serializers_admin.py

@ -414,7 +414,7 @@ class AdminHadisCorrectionSerializer(serializers.ModelSerializer):
ret["images"] = [ ret["images"] = [
{ {
"id": img.id, "id": img.id,
"image": request.build_absolute_uri(img.image.url) if request and img.image else img.image.url
"image": absolute_https_url(img.image.url, request) if request and img.image else absolute_https_url(img.image.url)
} }
for img in images for img in images
] ]
@ -533,7 +533,7 @@ class AdminHadisInterpretationSerializer(serializers.ModelSerializer):
ret["images"] = [ ret["images"] = [
{ {
"id": img.id, "id": img.id,
"image": request.build_absolute_uri(img.image.url) if request and img.image else img.image.url
"image": absolute_https_url(img.image.url, request) if request and img.image else absolute_https_url(img.image.url)
} }
for img in images for img in images
] ]
@ -1197,7 +1197,7 @@ class AdminTransmitterOriginalTextSerializer(serializers.ModelSerializer):
ret["images"] = [ ret["images"] = [
{ {
"id": img.id, "id": img.id,
"image": request.build_absolute_uri(img.image.url) if request and img.image else img.image.url
"image": absolute_https_url(img.image.url, request) if request and img.image else absolute_https_url(img.image.url)
} }
for img in (ref.images.all() if ref else []) for img in (ref.images.all() if ref else [])
] ]

3
apps/hadis/views/category.py

@ -5,6 +5,7 @@ from utils.pagination import NoPagination
from django.db.models import Q from django.db.models import Q
from collections import defaultdict from collections import defaultdict
from utils.pagination import StandardResultsSetPagination from utils.pagination import StandardResultsSetPagination
from utils import absolute_https_url
from ..models import HadisSect, HadisCategory,Hadis from ..models import HadisSect, HadisCategory,Hadis
from apps.bookmark.serializers.bookmark import BookmarkStatusSerializer from apps.bookmark.serializers.bookmark import BookmarkStatusSerializer
from ..serializers import ( from ..serializers import (
@ -218,7 +219,7 @@ class HadisCategoryTreeView(ListAPIView):
def _get_thumbnail_url(self, category, request): def _get_thumbnail_url(self, category, request):
"""Get absolute thumbnail URL""" """Get absolute thumbnail URL"""
if hasattr(category, 'thumbnail') and category.thumbnail: if hasattr(category, 'thumbnail') and category.thumbnail:
return request.build_absolute_uri(category.thumbnail.url) if request else category.thumbnail.url
return absolute_https_url(category.thumbnail.url, request)
return None return None
def _get_xmind_url(self, category, request): def _get_xmind_url(self, category, request):

Loading…
Cancel
Save