diff --git a/config/settings/base.py b/config/settings/base.py index 6c9b10c..333066c 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -119,8 +119,6 @@ MIDDLEWARE = [ "whitenoise.middleware.WhiteNoiseMiddleware", 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', - # Subdomain routing - must be before LocaleMiddleware - 'config.subdomain_middleware.SubdomainRoutingMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', diff --git a/config/subdomain_middleware.py b/config/subdomain_middleware.py deleted file mode 100644 index 2b52050..0000000 --- a/config/subdomain_middleware.py +++ /dev/null @@ -1,106 +0,0 @@ -""" -Subdomain Routing Middleware - -Routes requests to different URL configurations based on the subdomain. -This allows clean separation of admin, API, and docs URLs. - -Subdomains: -- admin.imamjavad.nwhco.ir → config.urls_admin -- api.imamjavad.nwhco.ir → config.urls_api -- docs.imamjavad.nwhco.ir → config.urls_docs -- imamjavad.nwhco.ir → config.urls (main/frontend) -""" -from django.utils.deprecation import MiddlewareMixin -from django.conf import settings - - -class SubdomainRoutingMiddleware(MiddlewareMixin): - """ - Middleware that sets the ROOT_URLCONF based on the request's subdomain. - """ - - # Mapping of subdomain prefixes to URL configurations - SUBDOMAIN_URLCONFS = { - 'admin': 'config.urls_admin', # Admin + Swagger/Redoc - } - - # List of main domains (without subdomain routing) - MAIN_DOMAINS = [ - 'imamjavad.nwhco.ir', - 'imamjavad.newhorizonco.uk', - 'dovoodi.nwhco.ir', - 'dovodi.newhorizonco.uk', - 'localhost', - '127.0.0.1', - ] - - def process_request(self, request): - """ - Determine the subdomain and set the appropriate ROOT_URLCONF. - """ - # Get host from request (handles X-Forwarded-Host for proxied requests) - host = request.get_host().split(':')[0].lower() - - # Check if this is a subdomain request - subdomain = self._extract_subdomain(host) - - if subdomain and subdomain in self.SUBDOMAIN_URLCONFS: - # Set the URL configuration for this subdomain - request.urlconf = self.SUBDOMAIN_URLCONFS[subdomain] - # Store subdomain info for potential use in views - request.subdomain = subdomain - else: - # Use default URL configuration - request.subdomain = None - - return None - - def _extract_subdomain(self, host): - """ - Extract the subdomain from the host. - - Examples: - - admin.imamjavad.nwhco.ir → 'admin' - - api.imamjavad.nwhco.ir → 'api' - - imamjavad.nwhco.ir → None - """ - # Check against main domains - for main_domain in self.MAIN_DOMAINS: - if host == main_domain: - return None - - # Check if host is a subdomain of a main domain - if host.endswith('.' + main_domain): - # Extract subdomain part - subdomain = host[:-len('.' + main_domain)] - # Only return first-level subdomain - if '.' not in subdomain: - return subdomain - - # Also check against ALLOWED_HOSTS for flexibility - for allowed_host in getattr(settings, 'ALLOWED_HOSTS', []): - if allowed_host.startswith('.'): - # Wildcard domain like .nwhco.ir - base_domain = allowed_host[1:] - if host.endswith(base_domain) and host != base_domain: - subdomain = host[:-len(base_domain)].rstrip('.') - if '.' not in subdomain: - return subdomain - - return None - - -def get_subdomain(request): - """ - Utility function to get the current subdomain from request. - Can be used in views or templates. - """ - return getattr(request, 'subdomain', None) - - -def is_admin_subdomain(request): - """Check if current request is on admin subdomain.""" - return get_subdomain(request) == 'admin' - - - diff --git a/config/urls_admin.py b/config/urls_admin.py deleted file mode 100644 index 4266f76..0000000 --- a/config/urls_admin.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -URL configuration for Admin Subdomain (admin.imamjavad.nwhco.ir) - -This handles all admin-related URLs and Swagger/Redoc when accessed via the admin subdomain. -""" -from django.urls import path, include, re_path -from django.conf import settings -from django.conf.urls.static import static -from django.conf.urls.i18n import i18n_patterns - -from drf_yasg.views import get_schema_view -from drf_yasg import openapi - -from utils.admin import project_admin_site, dovoodi_admin_site, HomeView -from apps.api.views import CustomAPIDocumentationView, CustomSwaggerView, SwaggerTokenAuthView, clear_swagger_auth -from apps.api.permissions import IsAdminOrSwaggerToken -from apps.api.decorators import swagger_auth_required - -# Schema view for documentation -schema_view = get_schema_view( - openapi.Info( - title="Imam Javad API", - default_version='v1', - description="Comprehensive API documentation for the Imam Javad educational platform", - contact=openapi.Contact(email="contact@imamjavad.com"), - license=openapi.License(name="MIT License"), - ), - public=False, - permission_classes=(IsAdminOrSwaggerToken,), -) - -# Swagger URL patterns -swagger_urlpatterns = [ - path('swagger-auth/', SwaggerTokenAuthView.as_view(), name='swagger-token-auth'), - path('swagger-auth/clear/', clear_swagger_auth, name='clear-swagger-auth'), - re_path(r'^swagger(?P\.json|\.yaml)$', - swagger_auth_required(schema_view.without_ui(cache_timeout=0)), - name='schema-json'), - path('swagger/', CustomSwaggerView.as_view(), name='schema-swagger-ui'), - re_path(r'^redoc/$', - swagger_auth_required(schema_view.with_ui('redoc', cache_timeout=0)), - name='schema-redoc'), -] - -urlpatterns = [ - # Root redirect to admin - path("", HomeView.as_view(), name="home"), - path("i18n/", include("django.conf.urls.i18n")), - path('filer/', include('filer.urls')), -] - -# i18n admin + swagger patterns -urlpatterns += i18n_patterns( - path("imam-javad/admin/", project_admin_site.urls), - path("dovoodi/admin/", dovoodi_admin_site.urls), - path('docs/', CustomAPIDocumentationView.as_view(), name='docs-index'), - *swagger_urlpatterns, - path('filer/', include('filer.urls')), -) - -if settings.DEBUG: - urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)