Added login api
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
14
acer-env/lib/python3.10/site-packages/corsheaders/apps.py
Normal file
14
acer-env/lib/python3.10/site-packages/corsheaders/apps.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.core.checks import Tags, register
|
||||
|
||||
from corsheaders.checks import check_settings
|
||||
|
||||
|
||||
class CorsHeadersAppConfig(AppConfig):
|
||||
name = "corsheaders"
|
||||
verbose_name = "django-cors-headers"
|
||||
|
||||
def ready(self) -> None:
|
||||
register(Tags.security)(check_settings)
|
||||
164
acer-env/lib/python3.10/site-packages/corsheaders/checks.py
Normal file
164
acer-env/lib/python3.10/site-packages/corsheaders/checks.py
Normal file
@@ -0,0 +1,164 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from collections.abc import Sequence
|
||||
from typing import Any
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.conf import settings
|
||||
from django.core.checks import Error
|
||||
|
||||
from corsheaders.conf import conf
|
||||
|
||||
re_type = type(re.compile(""))
|
||||
|
||||
|
||||
def check_settings(app_configs: list[AppConfig], **kwargs: Any) -> list[Error]:
|
||||
errors = []
|
||||
|
||||
if not is_sequence(conf.CORS_ALLOW_HEADERS, str):
|
||||
errors.append(
|
||||
Error(
|
||||
"CORS_ALLOW_HEADERS should be a sequence of strings.",
|
||||
id="corsheaders.E001",
|
||||
)
|
||||
)
|
||||
|
||||
if not is_sequence(conf.CORS_ALLOW_METHODS, str):
|
||||
errors.append(
|
||||
Error(
|
||||
"CORS_ALLOW_METHODS should be a sequence of strings.",
|
||||
id="corsheaders.E002",
|
||||
)
|
||||
)
|
||||
|
||||
if not isinstance(conf.CORS_ALLOW_CREDENTIALS, bool):
|
||||
errors.append( # type: ignore [unreachable]
|
||||
Error("CORS_ALLOW_CREDENTIALS should be a bool.", id="corsheaders.E003")
|
||||
)
|
||||
|
||||
if (
|
||||
not isinstance(conf.CORS_PREFLIGHT_MAX_AGE, int)
|
||||
or conf.CORS_PREFLIGHT_MAX_AGE < 0
|
||||
):
|
||||
errors.append(
|
||||
Error(
|
||||
(
|
||||
"CORS_PREFLIGHT_MAX_AGE should be an integer greater than "
|
||||
+ "or equal to zero."
|
||||
),
|
||||
id="corsheaders.E004",
|
||||
)
|
||||
)
|
||||
|
||||
if not isinstance(conf.CORS_ALLOW_ALL_ORIGINS, bool):
|
||||
if hasattr(settings, "CORS_ALLOW_ALL_ORIGINS"): # type: ignore [unreachable]
|
||||
allow_all_alias = "CORS_ALLOW_ALL_ORIGINS"
|
||||
else:
|
||||
allow_all_alias = "CORS_ORIGIN_ALLOW_ALL"
|
||||
errors.append(
|
||||
Error(
|
||||
f"{allow_all_alias} should be a bool.",
|
||||
id="corsheaders.E005",
|
||||
)
|
||||
)
|
||||
|
||||
if hasattr(settings, "CORS_ALLOWED_ORIGINS"):
|
||||
allowed_origins_alias = "CORS_ALLOWED_ORIGINS"
|
||||
else:
|
||||
allowed_origins_alias = "CORS_ORIGIN_WHITELIST"
|
||||
|
||||
if not is_sequence(conf.CORS_ALLOWED_ORIGINS, str):
|
||||
errors.append(
|
||||
Error(
|
||||
f"{allowed_origins_alias} should be a sequence of strings.",
|
||||
id="corsheaders.E006",
|
||||
)
|
||||
)
|
||||
else:
|
||||
special_origin_values = (
|
||||
# From 'security sensitive' contexts
|
||||
"null",
|
||||
# From files on Chrome on Android
|
||||
# https://bugs.chromium.org/p/chromium/issues/detail?id=991107
|
||||
"file://",
|
||||
)
|
||||
for origin in conf.CORS_ALLOWED_ORIGINS:
|
||||
if origin in special_origin_values:
|
||||
continue
|
||||
parsed = urlparse(origin)
|
||||
if parsed.scheme == "" or parsed.netloc == "":
|
||||
errors.append(
|
||||
Error(
|
||||
"Origin {} in {} is missing scheme or netloc".format(
|
||||
repr(origin), allowed_origins_alias
|
||||
),
|
||||
id="corsheaders.E013",
|
||||
hint=(
|
||||
"Add a scheme (e.g. https://) or netloc (e.g. "
|
||||
+ "example.com)."
|
||||
),
|
||||
)
|
||||
)
|
||||
else:
|
||||
# Only do this check in this case because if the scheme is not
|
||||
# provided, netloc ends up in path
|
||||
for part in ("path", "params", "query", "fragment"):
|
||||
if getattr(parsed, part) != "":
|
||||
errors.append(
|
||||
Error(
|
||||
"Origin {} in {} should not have {}".format(
|
||||
repr(origin), allowed_origins_alias, part
|
||||
),
|
||||
id="corsheaders.E014",
|
||||
)
|
||||
)
|
||||
|
||||
if hasattr(settings, "CORS_ALLOWED_ORIGIN_REGEXES"):
|
||||
allowed_regexes_alias = "CORS_ALLOWED_ORIGIN_REGEXES"
|
||||
else:
|
||||
allowed_regexes_alias = "CORS_ORIGIN_REGEX_WHITELIST"
|
||||
if not is_sequence(conf.CORS_ALLOWED_ORIGIN_REGEXES, (str, re_type)):
|
||||
errors.append(
|
||||
Error(
|
||||
"{} should be a sequence of strings and/or compiled regexes.".format(
|
||||
allowed_regexes_alias
|
||||
),
|
||||
id="corsheaders.E007",
|
||||
)
|
||||
)
|
||||
|
||||
if not is_sequence(conf.CORS_EXPOSE_HEADERS, str):
|
||||
errors.append(
|
||||
Error("CORS_EXPOSE_HEADERS should be a sequence.", id="corsheaders.E008")
|
||||
)
|
||||
|
||||
if not isinstance(conf.CORS_URLS_REGEX, (str, re_type)):
|
||||
errors.append(
|
||||
Error("CORS_URLS_REGEX should be a string or regex.", id="corsheaders.E009")
|
||||
)
|
||||
|
||||
if not isinstance(conf.CORS_REPLACE_HTTPS_REFERER, bool):
|
||||
errors.append( # type: ignore [unreachable]
|
||||
Error("CORS_REPLACE_HTTPS_REFERER should be a bool.", id="corsheaders.E011")
|
||||
)
|
||||
|
||||
if hasattr(settings, "CORS_MODEL"):
|
||||
errors.append(
|
||||
Error(
|
||||
(
|
||||
"The CORS_MODEL setting has been removed - see "
|
||||
+ "django-cors-headers' HISTORY."
|
||||
),
|
||||
id="corsheaders.E012",
|
||||
)
|
||||
)
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def is_sequence(thing: Any, type_or_types: type[Any] | tuple[type[Any], ...]) -> bool:
|
||||
return isinstance(thing, Sequence) and all(
|
||||
isinstance(x, type_or_types) for x in thing
|
||||
)
|
||||
70
acer-env/lib/python3.10/site-packages/corsheaders/conf.py
Normal file
70
acer-env/lib/python3.10/site-packages/corsheaders/conf.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Pattern, Sequence, Tuple, Union, cast
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
# Kept here for backwards compatibility
|
||||
from corsheaders.defaults import default_headers, default_methods
|
||||
|
||||
|
||||
class Settings:
|
||||
"""
|
||||
Shadow Django's settings with a little logic
|
||||
"""
|
||||
|
||||
@property
|
||||
def CORS_ALLOW_HEADERS(self) -> Sequence[str]:
|
||||
return getattr(settings, "CORS_ALLOW_HEADERS", default_headers)
|
||||
|
||||
@property
|
||||
def CORS_ALLOW_METHODS(self) -> Sequence[str]:
|
||||
return getattr(settings, "CORS_ALLOW_METHODS", default_methods)
|
||||
|
||||
@property
|
||||
def CORS_ALLOW_CREDENTIALS(self) -> bool:
|
||||
return getattr(settings, "CORS_ALLOW_CREDENTIALS", False)
|
||||
|
||||
@property
|
||||
def CORS_PREFLIGHT_MAX_AGE(self) -> int:
|
||||
return getattr(settings, "CORS_PREFLIGHT_MAX_AGE", 86400)
|
||||
|
||||
@property
|
||||
def CORS_ALLOW_ALL_ORIGINS(self) -> bool:
|
||||
return getattr(
|
||||
settings,
|
||||
"CORS_ALLOW_ALL_ORIGINS",
|
||||
getattr(settings, "CORS_ORIGIN_ALLOW_ALL", False),
|
||||
)
|
||||
|
||||
@property
|
||||
def CORS_ALLOWED_ORIGINS(self) -> list[str] | tuple[str]:
|
||||
value = getattr(
|
||||
settings,
|
||||
"CORS_ALLOWED_ORIGINS",
|
||||
getattr(settings, "CORS_ORIGIN_WHITELIST", ()),
|
||||
)
|
||||
return cast(Union[List[str], Tuple[str]], value)
|
||||
|
||||
@property
|
||||
def CORS_ALLOWED_ORIGIN_REGEXES(self) -> Sequence[str | Pattern[str]]:
|
||||
return getattr(
|
||||
settings,
|
||||
"CORS_ALLOWED_ORIGIN_REGEXES",
|
||||
getattr(settings, "CORS_ORIGIN_REGEX_WHITELIST", ()),
|
||||
)
|
||||
|
||||
@property
|
||||
def CORS_EXPOSE_HEADERS(self) -> Sequence[str]:
|
||||
return getattr(settings, "CORS_EXPOSE_HEADERS", ())
|
||||
|
||||
@property
|
||||
def CORS_URLS_REGEX(self) -> str | Pattern[str]:
|
||||
return getattr(settings, "CORS_URLS_REGEX", r"^.*$")
|
||||
|
||||
@property
|
||||
def CORS_REPLACE_HTTPS_REFERER(self) -> bool:
|
||||
return getattr(settings, "CORS_REPLACE_HTTPS_REFERER", False)
|
||||
|
||||
|
||||
conf = Settings()
|
||||
@@ -0,0 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
default_headers = (
|
||||
"accept",
|
||||
"accept-encoding",
|
||||
"authorization",
|
||||
"content-type",
|
||||
"dnt",
|
||||
"origin",
|
||||
"user-agent",
|
||||
"x-csrftoken",
|
||||
"x-requested-with",
|
||||
)
|
||||
|
||||
default_methods = ("DELETE", "GET", "OPTIONS", "PATCH", "POST", "PUT")
|
||||
196
acer-env/lib/python3.10/site-packages/corsheaders/middleware.py
Normal file
196
acer-env/lib/python3.10/site-packages/corsheaders/middleware.py
Normal file
@@ -0,0 +1,196 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import Any
|
||||
from urllib.parse import ParseResult, urlparse
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.cache import patch_vary_headers
|
||||
from django.utils.deprecation import MiddlewareMixin
|
||||
|
||||
from corsheaders.conf import conf
|
||||
from corsheaders.signals import check_request_enabled
|
||||
|
||||
ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin"
|
||||
ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers"
|
||||
ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"
|
||||
ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers"
|
||||
ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods"
|
||||
ACCESS_CONTROL_MAX_AGE = "Access-Control-Max-Age"
|
||||
|
||||
|
||||
class CorsPostCsrfMiddleware(MiddlewareMixin):
|
||||
def _https_referer_replace_reverse(self, request: HttpRequest) -> None:
|
||||
"""
|
||||
Put the HTTP_REFERER back to its original value and delete the
|
||||
temporary storage
|
||||
"""
|
||||
if conf.CORS_REPLACE_HTTPS_REFERER and "ORIGINAL_HTTP_REFERER" in request.META:
|
||||
http_referer = request.META["ORIGINAL_HTTP_REFERER"]
|
||||
request.META["HTTP_REFERER"] = http_referer
|
||||
del request.META["ORIGINAL_HTTP_REFERER"]
|
||||
|
||||
def process_request(self, request: HttpRequest) -> None:
|
||||
self._https_referer_replace_reverse(request)
|
||||
return None
|
||||
|
||||
def process_view(
|
||||
self,
|
||||
request: HttpRequest,
|
||||
callback: Any,
|
||||
callback_args: Any,
|
||||
callback_kwargs: Any,
|
||||
) -> None:
|
||||
self._https_referer_replace_reverse(request)
|
||||
return None
|
||||
|
||||
|
||||
class CorsMiddleware(MiddlewareMixin):
|
||||
def _https_referer_replace(self, request: HttpRequest) -> None:
|
||||
"""
|
||||
When https is enabled, django CSRF checking includes referer checking
|
||||
which breaks when using CORS. This function updates the HTTP_REFERER
|
||||
header to make sure it matches HTTP_HOST, provided that our cors logic
|
||||
succeeds
|
||||
"""
|
||||
origin = request.META.get("HTTP_ORIGIN")
|
||||
|
||||
if (
|
||||
request.is_secure()
|
||||
and origin
|
||||
and "ORIGINAL_HTTP_REFERER" not in request.META
|
||||
):
|
||||
|
||||
url = urlparse(origin)
|
||||
if (
|
||||
not conf.CORS_ALLOW_ALL_ORIGINS
|
||||
and not self.origin_found_in_white_lists(origin, url)
|
||||
):
|
||||
return
|
||||
|
||||
try:
|
||||
http_referer = request.META["HTTP_REFERER"]
|
||||
http_host = "https://%s/" % request.META["HTTP_HOST"]
|
||||
request.META = request.META.copy()
|
||||
request.META["ORIGINAL_HTTP_REFERER"] = http_referer
|
||||
request.META["HTTP_REFERER"] = http_host
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def process_request(self, request: HttpRequest) -> HttpResponse | None:
|
||||
"""
|
||||
If CORS preflight header, then create an
|
||||
empty body response (200 OK) and return it
|
||||
|
||||
Django won't bother calling any other request
|
||||
view/exception middleware along with the requested view;
|
||||
it will call any response middlewares
|
||||
"""
|
||||
request._cors_enabled = self.is_enabled(request)
|
||||
if request._cors_enabled:
|
||||
if conf.CORS_REPLACE_HTTPS_REFERER:
|
||||
self._https_referer_replace(request)
|
||||
|
||||
if (
|
||||
request.method == "OPTIONS"
|
||||
and "HTTP_ACCESS_CONTROL_REQUEST_METHOD" in request.META
|
||||
):
|
||||
response = HttpResponse()
|
||||
response["Content-Length"] = "0"
|
||||
return response
|
||||
return None
|
||||
|
||||
def process_view(
|
||||
self,
|
||||
request: HttpRequest,
|
||||
callback: Any,
|
||||
callback_args: Any,
|
||||
callback_kwargs: Any,
|
||||
) -> None:
|
||||
"""
|
||||
Do the referer replacement here as well
|
||||
"""
|
||||
if request._cors_enabled and conf.CORS_REPLACE_HTTPS_REFERER:
|
||||
self._https_referer_replace(request)
|
||||
return None
|
||||
|
||||
def process_response(
|
||||
self, request: HttpRequest, response: HttpResponse
|
||||
) -> HttpResponse:
|
||||
"""
|
||||
Add the respective CORS headers
|
||||
"""
|
||||
enabled = getattr(request, "_cors_enabled", None)
|
||||
if enabled is None:
|
||||
enabled = self.is_enabled(request)
|
||||
|
||||
if not enabled:
|
||||
return response
|
||||
|
||||
patch_vary_headers(response, ["Origin"])
|
||||
|
||||
origin = request.META.get("HTTP_ORIGIN")
|
||||
if not origin:
|
||||
return response
|
||||
|
||||
try:
|
||||
url = urlparse(origin)
|
||||
except ValueError:
|
||||
return response
|
||||
|
||||
if conf.CORS_ALLOW_CREDENTIALS:
|
||||
response[ACCESS_CONTROL_ALLOW_CREDENTIALS] = "true"
|
||||
|
||||
if (
|
||||
not conf.CORS_ALLOW_ALL_ORIGINS
|
||||
and not self.origin_found_in_white_lists(origin, url)
|
||||
and not self.check_signal(request)
|
||||
):
|
||||
return response
|
||||
|
||||
if conf.CORS_ALLOW_ALL_ORIGINS and not conf.CORS_ALLOW_CREDENTIALS:
|
||||
response[ACCESS_CONTROL_ALLOW_ORIGIN] = "*"
|
||||
else:
|
||||
response[ACCESS_CONTROL_ALLOW_ORIGIN] = origin
|
||||
|
||||
if len(conf.CORS_EXPOSE_HEADERS):
|
||||
response[ACCESS_CONTROL_EXPOSE_HEADERS] = ", ".join(
|
||||
conf.CORS_EXPOSE_HEADERS
|
||||
)
|
||||
|
||||
if request.method == "OPTIONS":
|
||||
response[ACCESS_CONTROL_ALLOW_HEADERS] = ", ".join(conf.CORS_ALLOW_HEADERS)
|
||||
response[ACCESS_CONTROL_ALLOW_METHODS] = ", ".join(conf.CORS_ALLOW_METHODS)
|
||||
if conf.CORS_PREFLIGHT_MAX_AGE:
|
||||
response[ACCESS_CONTROL_MAX_AGE] = str(conf.CORS_PREFLIGHT_MAX_AGE)
|
||||
|
||||
return response
|
||||
|
||||
def origin_found_in_white_lists(self, origin: str, url: ParseResult) -> bool:
|
||||
return (
|
||||
(origin == "null" and origin in conf.CORS_ALLOWED_ORIGINS)
|
||||
or self._url_in_whitelist(url)
|
||||
or self.regex_domain_match(origin)
|
||||
)
|
||||
|
||||
def regex_domain_match(self, origin: str) -> bool:
|
||||
return any(
|
||||
re.match(domain_pattern, origin)
|
||||
for domain_pattern in conf.CORS_ALLOWED_ORIGIN_REGEXES
|
||||
)
|
||||
|
||||
def is_enabled(self, request: HttpRequest) -> bool:
|
||||
return bool(
|
||||
re.match(conf.CORS_URLS_REGEX, request.path_info)
|
||||
) or self.check_signal(request)
|
||||
|
||||
def check_signal(self, request: HttpRequest) -> bool:
|
||||
signal_responses = check_request_enabled.send(sender=None, request=request)
|
||||
return any(return_value for function, return_value in signal_responses)
|
||||
|
||||
def _url_in_whitelist(self, url: ParseResult) -> bool:
|
||||
origins = [urlparse(o) for o in conf.CORS_ALLOWED_ORIGINS]
|
||||
return any(
|
||||
origin.scheme == url.scheme and origin.netloc == url.netloc
|
||||
for origin in origins
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from django.dispatch import Signal
|
||||
|
||||
# If any attached handler returns Truthy, CORS will be allowed for the request.
|
||||
# This can be used to build custom logic into the request handling when the
|
||||
# configuration doesn't work.
|
||||
check_request_enabled = Signal()
|
||||
Reference in New Issue
Block a user