Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/corsheaders/checks.py: 61%
56 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1from __future__ import annotations
3import re
4from collections.abc import Sequence
5from typing import Any
6from urllib.parse import urlparse
8from django.apps import AppConfig
9from django.conf import settings
10from django.core.checks import Error
12from corsheaders.conf import conf
14re_type = type(re.compile(""))
17def check_settings(app_configs: list[AppConfig], **kwargs: Any) -> list[Error]:
18 errors = []
20 if not is_sequence(conf.CORS_ALLOW_HEADERS, str): 20 ↛ 21line 20 didn't jump to line 21, because the condition on line 20 was never true
21 errors.append(
22 Error(
23 "CORS_ALLOW_HEADERS should be a sequence of strings.",
24 id="corsheaders.E001",
25 )
26 )
28 if not is_sequence(conf.CORS_ALLOW_METHODS, str): 28 ↛ 29line 28 didn't jump to line 29, because the condition on line 28 was never true
29 errors.append(
30 Error(
31 "CORS_ALLOW_METHODS should be a sequence of strings.",
32 id="corsheaders.E002",
33 )
34 )
36 if not isinstance(conf.CORS_ALLOW_CREDENTIALS, bool): 36 ↛ 37line 36 didn't jump to line 37, because the condition on line 36 was never true
37 errors.append( # type: ignore [unreachable]
38 Error("CORS_ALLOW_CREDENTIALS should be a bool.", id="corsheaders.E003")
39 )
41 if ( 41 ↛ 45line 41 didn't jump to line 45
42 not isinstance(conf.CORS_PREFLIGHT_MAX_AGE, int)
43 or conf.CORS_PREFLIGHT_MAX_AGE < 0
44 ):
45 errors.append(
46 Error(
47 (
48 "CORS_PREFLIGHT_MAX_AGE should be an integer greater than "
49 + "or equal to zero."
50 ),
51 id="corsheaders.E004",
52 )
53 )
55 if not isinstance(conf.CORS_ALLOW_ALL_ORIGINS, bool): 55 ↛ 56line 55 didn't jump to line 56, because the condition on line 55 was never true
56 if hasattr(settings, "CORS_ALLOW_ALL_ORIGINS"): # type: ignore [unreachable]
57 allow_all_alias = "CORS_ALLOW_ALL_ORIGINS"
58 else:
59 allow_all_alias = "CORS_ORIGIN_ALLOW_ALL"
60 errors.append(
61 Error(
62 f"{allow_all_alias} should be a bool.",
63 id="corsheaders.E005",
64 )
65 )
67 if hasattr(settings, "CORS_ALLOWED_ORIGINS"): 67 ↛ 70line 67 didn't jump to line 70, because the condition on line 67 was never false
68 allowed_origins_alias = "CORS_ALLOWED_ORIGINS"
69 else:
70 allowed_origins_alias = "CORS_ORIGIN_WHITELIST"
72 if not is_sequence(conf.CORS_ALLOWED_ORIGINS, str): 72 ↛ 73line 72 didn't jump to line 73, because the condition on line 72 was never true
73 errors.append(
74 Error(
75 f"{allowed_origins_alias} should be a sequence of strings.",
76 id="corsheaders.E006",
77 )
78 )
79 else:
80 special_origin_values = (
81 # From 'security sensitive' contexts
82 "null",
83 # From files on Chrome on Android
84 # https://bugs.chromium.org/p/chromium/issues/detail?id=991107
85 "file://",
86 )
87 for origin in conf.CORS_ALLOWED_ORIGINS:
88 if origin in special_origin_values: 88 ↛ 89line 88 didn't jump to line 89, because the condition on line 88 was never true
89 continue
90 parsed = urlparse(origin)
91 if parsed.scheme == "" or parsed.netloc == "": 91 ↛ 92line 91 didn't jump to line 92, because the condition on line 91 was never true
92 errors.append(
93 Error(
94 "Origin {} in {} is missing scheme or netloc".format(
95 repr(origin), allowed_origins_alias
96 ),
97 id="corsheaders.E013",
98 hint=(
99 "Add a scheme (e.g. https://) or netloc (e.g. "
100 + "example.com)."
101 ),
102 )
103 )
104 else:
105 # Only do this check in this case because if the scheme is not
106 # provided, netloc ends up in path
107 for part in ("path", "params", "query", "fragment"):
108 if getattr(parsed, part) != "": 108 ↛ 109line 108 didn't jump to line 109, because the condition on line 108 was never true
109 errors.append(
110 Error(
111 "Origin {} in {} should not have {}".format(
112 repr(origin), allowed_origins_alias, part
113 ),
114 id="corsheaders.E014",
115 )
116 )
118 if hasattr(settings, "CORS_ALLOWED_ORIGIN_REGEXES"): 118 ↛ 119line 118 didn't jump to line 119, because the condition on line 118 was never true
119 allowed_regexes_alias = "CORS_ALLOWED_ORIGIN_REGEXES"
120 else:
121 allowed_regexes_alias = "CORS_ORIGIN_REGEX_WHITELIST"
122 if not is_sequence(conf.CORS_ALLOWED_ORIGIN_REGEXES, (str, re_type)): 122 ↛ 123line 122 didn't jump to line 123, because the condition on line 122 was never true
123 errors.append(
124 Error(
125 "{} should be a sequence of strings and/or compiled regexes.".format(
126 allowed_regexes_alias
127 ),
128 id="corsheaders.E007",
129 )
130 )
132 if not is_sequence(conf.CORS_EXPOSE_HEADERS, str): 132 ↛ 133line 132 didn't jump to line 133, because the condition on line 132 was never true
133 errors.append(
134 Error("CORS_EXPOSE_HEADERS should be a sequence.", id="corsheaders.E008")
135 )
137 if not isinstance(conf.CORS_URLS_REGEX, (str, re_type)): 137 ↛ 138line 137 didn't jump to line 138, because the condition on line 137 was never true
138 errors.append(
139 Error("CORS_URLS_REGEX should be a string or regex.", id="corsheaders.E009")
140 )
142 if not isinstance(conf.CORS_REPLACE_HTTPS_REFERER, bool): 142 ↛ 143line 142 didn't jump to line 143, because the condition on line 142 was never true
143 errors.append( # type: ignore [unreachable]
144 Error("CORS_REPLACE_HTTPS_REFERER should be a bool.", id="corsheaders.E011")
145 )
147 if hasattr(settings, "CORS_MODEL"): 147 ↛ 148line 147 didn't jump to line 148, because the condition on line 147 was never true
148 errors.append(
149 Error(
150 (
151 "The CORS_MODEL setting has been removed - see "
152 + "django-cors-headers' HISTORY."
153 ),
154 id="corsheaders.E012",
155 )
156 )
158 return errors
161def is_sequence(thing: Any, type_or_types: type[Any] | tuple[type[Any], ...]) -> bool:
162 return isinstance(thing, Sequence) and all(
163 isinstance(x, type_or_types) for x in thing
164 )