Coverage for conf/settings/security.py: 86%

26 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 06:14 +0000

1from socket import gethostbyname, gethostname 

2 

3from django.core.exceptions import ImproperlyConfigured 

4 

5from decouple import config 

6 

7from conf.settings.base import ENVIRONMENT, INSTALLED_APPS, MIDDLEWARE 

8 

9 

10# Quick-start development settings - unsuitable for production 

11# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ 

12 

13# SECURITY WARNING: keep the secret key used in production secret! 

14SECRET_KEY = config("DJANGO_SECRET_KEY") # required 

15 

16# SECURITY WARNING: don't run with debug turned on in production! 

17DEBUG = config("DJANGO_DEBUG_ENABLED", default=False, cast=bool) 

18 

19# The domain we treat as "canonical" for this API instance, e.g., `api.` subdomain for production 

20CANONICAL_DOMAIN: str = config("CANONICAL_DOMAIN") # required 

21 

22_proto = "http" if "localhost" in CANONICAL_DOMAIN else "https" 

23CANONICAL_ORIGIN: str = f"{_proto}://{CANONICAL_DOMAIN}" 

24 

25# Additional domains we serve for this API instance, e.g., `api-production.` subdomain for production 

26ALTERNATIVE_DOMAINS: list[str] = config( 

27 "ALTERNATIVE_DOMAINS", default="", cast=lambda x: x.split(",") 

28) 

29 

30ALL_DOMAINS = [CANONICAL_DOMAIN] + ALTERNATIVE_DOMAINS 

31 

32ALLOWED_HOSTS = [ 

33 # Strip ports off hosts, as ALLOWED_HOSTS does not work with ports, e.g., `localhost:8000` needs to be just `localhost` 

34 domain.split(":")[0] 

35 for domain in ALL_DOMAINS 

36] + [ 

37 gethostname(), 

38 gethostbyname(gethostname()), 

39] 

40 

41if DEBUG: 41 ↛ 50line 41 didn't jump to line 50 because the condition on line 41 was always true

42 ALLOWED_HOSTS += [ 

43 "dev.openverse.test", # used in local development 

44 "127.0.0.1", 

45 "0.0.0.0", 

46 ] 

47 

48# Trusted origins for CSRF 

49# https://docs.djangoproject.com/en/4.2/ref/settings/#csrf-trusted-origins 

50CSRF_TRUSTED_ORIGINS = [f"{_proto}://{domain}" for domain in ALL_DOMAINS] 

51 

52# Allow anybody to access the API from any domain 

53if "corsheaders" not in INSTALLED_APPS: 

54 INSTALLED_APPS.append("corsheaders") 

55 

56middleware = "corsheaders.middleware.CorsMiddleware" 

57if middleware not in MIDDLEWARE: 

58 MIDDLEWARE.insert(0, middleware) 

59 

60CORS_ALLOW_ALL_ORIGINS = True 

61# https://github.com/adamchainz/django-cors-headers?tab=readme-ov-file#cors_expose_headers-sequencestr 

62# These headers are required for search response time analytics 

63CORS_EXPOSE_HEADERS = [ 

64 "cf-cache-status", 

65 "cf-ray", 

66 "date", 

67] 

68 

69# Proxy handling, for production 

70if config("DJANGO_IS_PROXIED", default=True, cast=bool): 70 ↛ 72line 70 didn't jump to line 72 because the condition on line 70 was never true

71 # https://docs.djangoproject.com/en/4.0/ref/settings/#secure-proxy-ssl-header 

72 SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") 

73 

74# Adding DJANGO_SECRET_KEY check 

75if SECRET_KEY == "example_key" and ENVIRONMENT != "local": 75 ↛ 76line 75 didn't jump to line 76 because the condition on line 75 was never true

76 raise ImproperlyConfigured( 

77 "DJANGO_SECRET_KEY must not be 'example_key' in non-local environments." 

78 )