Exemple #1
0
def validate_auth_user(headers: HttpHeaders,
                       gateway_config: "GatewayConfig") -> bool:
    username = gateway_config.connection_params["webhook_user"]
    password = gateway_config.connection_params["webhook_user_password"]
    auth_header: Optional[str] = headers.get("Authorization")
    if not auth_header and not username:
        return True
    if auth_header and not username:
        return False
    if not auth_header and username:
        return False

    split_auth = auth_header.split(maxsplit=1)  # type: ignore
    prefix = "BASIC"

    if len(split_auth) != 2 or split_auth[0].upper() != prefix:
        return False

    auth = split_auth[1]
    try:
        decoded_auth = base64.b64decode(auth).decode()
        request_username, request_password = decoded_auth.split(":")
        user_is_correct = request_username == username
        if user_is_correct and check_password(request_password, password):
            return True
    except binascii.Error:
        pass
    return False
Exemple #2
0
def mirror_request_to_elasticsearch(request: Union[HttpRequest, Request]):
    """ Duplicate request and send-again against this server, with the ES header attached to mirror
        non-elasticsearch load against elasticsearch for load testing
    """
    url = request.build_absolute_uri()
    data = json.dumps(request.data)
    headers = {
        **request.headers,
        HttpHeaders.parse_header_name(EXPERIMENTAL_API_HEADER):
        ELASTICSEARCH_HEADER_VALUE,
    }

    logger.warning(
        "Mirroring inbound request with elasticsearch experimental header.")

    # NOTE: Purposely desiring an immediate timeout, with ignoring of that timeout error,
    # since this is a fire-and-forget way to siphon off duplicate load-testing traffic to the server,
    # without disrupting the primary request
    try:
        if request.method == "GET":
            requests.get(url, data, headers=headers, timeout=0.01)
        elif request.method == "POST":
            requests.post(url, data, headers=headers, timeout=0.01)
        else:
            pass
    # TODO: Preemptive timeout still seems to cause the request to be recorded as 500 with:
    # ConnectionResetError: [Errno 54] Connection reset by peer.
    # See if this can be avoided in a different way than forcing an early timeout
    except (requests.exceptions.Timeout, ConnectionResetError):
        pass
    except Exception as exc:
        logger.exception("Mirrored request using Elasticsearch failed",
                         exc_info=exc)
Exemple #3
0
 def test_parse_header_name(self):
     tests = (
         ('PATH_INFO', None),
         ('HTTP_ACCEPT', 'Accept'),
         ('HTTP_USER_AGENT', 'User-Agent'),
         ('HTTP_X_FORWARDED_PROTO', 'X-Forwarded-Proto'),
         ('CONTENT_TYPE', 'Content-Type'),
         ('CONTENT_LENGTH', 'Content-Length'),
     )
     for header, expected in tests:
         with self.subTest(header=header):
             self.assertEqual(HttpHeaders.parse_header_name(header), expected)
Exemple #4
0
 def test_parse_header_name(self):
     tests = (
         ('PATH_INFO', None),
         ('HTTP_ACCEPT', 'Accept'),
         ('HTTP_USER_AGENT', 'User-Agent'),
         ('HTTP_X_FORWARDED_PROTO', 'X-Forwarded-Proto'),
         ('CONTENT_TYPE', 'Content-Type'),
         ('CONTENT_LENGTH', 'Content-Length'),
     )
     for header, expected in tests:
         with self.subTest(header=header):
             self.assertEqual(HttpHeaders.parse_header_name(header), expected)
Exemple #5
0
 def test_basic(self):
     environ = {
         'CONTENT_TYPE': 'text/html',
         'CONTENT_LENGTH': '100',
         'HTTP_HOST': 'example.com',
     }
     headers = HttpHeaders(environ)
     self.assertEqual(sorted(headers), ['Content-Length', 'Content-Type', 'Host'])
     self.assertEqual(headers, {
         'Content-Type': 'text/html',
         'Content-Length': '100',
         'Host': 'example.com',
     })
Exemple #6
0
 def test_parse_header_name(self):
     tests = (
         ("PATH_INFO", None),
         ("HTTP_ACCEPT", "Accept"),
         ("HTTP_USER_AGENT", "User-Agent"),
         ("HTTP_X_FORWARDED_PROTO", "X-Forwarded-Proto"),
         ("CONTENT_TYPE", "Content-Type"),
         ("CONTENT_LENGTH", "Content-Length"),
     )
     for header, expected in tests:
         with self.subTest(header=header):
             self.assertEqual(HttpHeaders.parse_header_name(header),
                              expected)
Exemple #7
0
    def _build_request(
        self, method: str, path: str, data: Dict, request_params: Any
    ) -> Mock:
        request = Mock()
        request.method = method
        request.path = path
        request.body = ""
        request.COOKIES = {}
        request._dont_enforce_csrf_checks = True
        request.is_secure.return_value = False
        request.build_absolute_uri = build_absolute_uri

        if "user" not in request_params:
            request.user.is_authenticated = False

        request.META = request_params.pop("META", {})
        request.FILES = request_params.pop("FILES", {})

        request.META.update(
            dict(
                [
                    (f"HTTP_{k.replace('-', '_')}", v)
                    for k, v in request_params.pop("headers", {}).items()
                ]
            )
        )
        if django.VERSION[:2] > (2, 1):
            from django.http.request import HttpHeaders

            request.headers = HttpHeaders(request.META)

        if isinstance(data, QueryDict):
            request.POST = data
        else:
            request.POST = QueryDict(mutable=True)
            for k, v in data.items():
                request.POST[k] = v

        if "?" in path:
            request.GET = QueryDict(path.split("?")[1])
        else:
            request.GET = QueryDict()

        for k, v in request_params.items():
            setattr(request, k, v)
        return request
Exemple #8
0
 def test_basic(self):
     environ = {
         "CONTENT_TYPE": "text/html",
         "CONTENT_LENGTH": "100",
         "HTTP_HOST": "example.com",
     }
     headers = HttpHeaders(environ)
     self.assertEqual(sorted(headers),
                      ["Content-Length", "Content-Type", "Host"])
     self.assertEqual(
         headers,
         {
             "Content-Type": "text/html",
             "Content-Length": "100",
             "Host": "example.com",
         },
     )
Exemple #9
0
    def _build_request(self, method: str, path: str, data: dict,
                       request_params: dict):
        request = Mock()
        request.method = method
        request.path = path
        request.body = ""
        request.COOKIES = {}

        if "user" not in request_params:
            request.user.is_authenticated = False

        request.META = request_params.pop("META", {})

        request.META.update(
            dict([(f"HTTP_{k}", v)
                  for k, v in request_params.pop("headers", {}).items()]))
        if django.VERSION[:2] > (2, 1):
            from django.http.request import HttpHeaders

            request.headers = HttpHeaders(request.META)

        if isinstance(data, QueryDict):
            request.POST = data
        else:
            request.POST = QueryDict(mutable=True)
            for k, v in data.items():
                request.POST[k] = v

        if "?" in path:
            request.GET = QueryDict(path.split("?")[1])
        else:
            request.GET = QueryDict()

        for k, v in request_params.items():
            setattr(request, k, v)
        return request
Exemple #10
0
 def _bad_token_message(self, reason, token_source):
     if token_source != 'POST':
         # Assume it is a settings.CSRF_HEADER_NAME value.
         header_name = HttpHeaders.parse_header_name(token_source)
         token_source = f'the {header_name!r} HTTP header'
     return f'CSRF token from {token_source} {reason}.'