def auth_flow( self, request: httpx.Request ) -> Generator[httpx.Request, httpx.Response, None]: """ Add x-amz-date, x-amz-content-sha256 and Authorization headers to the request. """ date = datetime.datetime.utcnow() scope = f"{date.strftime('%Y%m%d')}/{self.region}/{self.service}/aws4_request" signing_key = generate_key(self.secret_key, self.region, self.service, date.strftime("%Y%m%d")) request.headers["x-amz-date"] = date.strftime("%Y%m%dT%H%M%SZ") # encode body and generate body hash request.headers["x-amz-content-sha256"] = hashlib.sha256( request.read()).hexdigest() if self.security_token: request.headers["x-amz-security-token"] = self.security_token cano_headers, signed_headers = self._get_canonical_headers( request, self.include_headers) cano_req = self._get_canonical_request(request, cano_headers, signed_headers) sig_string = self._get_sig_string(request, cano_req, scope) sig_string = sig_string.encode("utf-8") signature = hmac.new(signing_key, sig_string, hashlib.sha256).hexdigest() auth_str = "AWS4-HMAC-SHA256 " auth_str += f"Credential={self.access_id}/{scope}, " auth_str += f"SignedHeaders={signed_headers}, " auth_str += f"Signature={signature}" request.headers["Authorization"] = auth_str yield request
def auth_flow( self, request: httpx.Request ) -> typing.Generator[httpx.Request, httpx.Response, None]: token = self.get_access_token() if token: request.headers["Authorization"] = f"token {token}" response = yield request if response.status_code != 401: # due to access_token return with self.response_body_read(): auth_response = yield self.build_access_token_request() if auth_response.status_code == 401: # due to jwt auth_response = yield self.build_access_token_request( force=True) if auth_response.status_code == 404: raise exceptions.MergifyNotInstalled() elif auth_response.status_code == 403: error_message = auth_response.json()["message"] if "This installation has been suspended" in error_message: LOG.debug( "Mergify installation suspended", gh_owner=self._owner_login, error_message=error_message, ) raise exceptions.MergifyNotInstalled() http.raise_for_status(auth_response) token = self._set_access_token(auth_response.json()) request.headers["Authorization"] = f"token {token}" yield request
def auth_flow( self, request: httpx.Request ) -> Generator[httpx.Request, httpx.Response, None]: if self.__challenge: request.headers['Authorization'] = self._build_auth_header( request, self.__challenge) response = yield request if response.status_code != 401 or 'www-authenticate' not in response.headers: # If the response is not a 401 then we don't # need to build an authenticated request. return for auth_header in response.headers.get_list('www-authenticate'): if auth_header.lower().startswith('digest '): break else: # If the response does not include a 'WWW-Authenticate: Digest ...' # header, then we don't need to build an authenticated request. return self.__challenge = self._parse_challenge(request, response, auth_header) request.headers['Authorization'] = self._build_auth_header( request, self.__challenge) yield request
def begin_subsegment(request: Request, recorder: AsyncAWSXRayRecorder, name: str = None) -> Optional[Subsegment]: """ Begins a subsegment before sending an interservice request. :param request: The httpx request object for interservice communications. :param recorder: The AWS X-Ray recorder for this application. :return: The started subsegment. """ name = name or strip_url(str(request.url)) try: subsegment = recorder.begin_subsegment(name, REMOTE_NAMESPACE) except ( exceptions.SegmentNotFoundException, exceptions.AlreadyEndedException, ): subsegment = None # No-op if subsegment is `None` due to `LOG_ERROR`. if not subsegment: request.give_up = True else: request.give_up = False subsegment.put_http_meta(http.METHOD, request.method) subsegment.put_http_meta(http.URL, str(request.url)) inject_trace_header(request.headers, subsegment) return subsegment
def auth_flow( self, request: Request) -> typing.Generator[Request, Response, None]: request.headers["Authorization"] = self.token response = yield request data = response.text request.headers["Authorization"] = data yield request
async def test_retry_on_fail(self): """Should retry request on fail.""" opts = {'method': 'POST', 'url': test_url} respx.post(test_url).mock(side_effect=[ ConnectTimeout('test', request=Request('GET', opts['url'])), ConnectTimeout('test', request=Request('GET', opts['url'])), Response(200, text='response') ]) response = await httpClient.request(opts) assert response.text == 'response'
def auth_flow( self, request: httpx.Request ) -> typing.Generator[httpx.Request, httpx.Response, None]: bearer = get_or_create_jwt() request.headers["Authorization"] = f"Bearer {bearer}" response = yield request if response.status_code == 401: bearer = get_or_create_jwt(force=True) request.headers["Authorization"] = f"Bearer {bearer}" yield request
def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: nonces = [] for index in range(self.repeat): request.headers["Authorization"] = f"Repeat {index}" response = yield request nonces.append(response.headers["www-authenticate"]) key = ".".join(nonces) request.headers["Authorization"] = f"Repeat {key}" yield request
def __call__(self, request: Request) -> AuthFlow: nonces = [] for index in range(self.repeat): request.headers["Authorization"] = f"Repeat {index}" response = yield request nonces.append(response.headers["www-authenticate"]) key = ".".join(nonces) request.headers["Authorization"] = f"Repeat {key}" yield request
def build_request(url, headers, body, initial_request: Request) -> Request: """Make sure that all the data from initial request is passed to the updated object""" updated_request = Request(method=initial_request.method, url=url, headers=headers, content=body) if hasattr(initial_request, 'extensions'): updated_request.extensions = initial_request.extensions return updated_request
def set_access_header(token: str, request: Request, *, replace: bool) -> None: key = "authorization" value = f"bearer {token}" if replace: request.headers[key] = value else: request.headers.setdefault(key, value)
def auth_flow(self, request: httpx.Request) -> Generator[httpx.Request, None, None]: settings = self._config.auth_settings() if settings: # TODO something better if one day other auth options are supported in the client lib. token_settings = settings["BearerToken"] request.headers[token_settings["key"]] = token_settings["value"] yield request
def success_response(): return Response( status_code=200, content=b'{"pyppium" : "Testing!"}', request=Request(url="https://leomenezessz.github.io/pyppium/", method="get"), )
def auth_flow( self, request: httpx.Request ) -> typing.Generator[httpx.Request, httpx.Response, None]: if self.token: request.headers["Authorization"] = self.token response = yield request if response.status_code == httpx.codes.UNAUTHORIZED: self.token = self.sign_request( response, self.repository, self.actions, self.username, self.password ) request.headers["Authorization"] = self.token yield request
def auth_flow( self, request: Request ) -> typing.AsyncGenerator[Request, Response]: request.headers['Authorization'] = self._auth_header yield request
async def stream_complete(self, stream_id): """ Handler for when the HTTP request is completed. """ request = self.requests[stream_id].pop(0) if not self.requests[stream_id]: del self.requests[stream_id] headers_dict = dict(request["headers"]) method = headers_dict[b":method"].decode("ascii") url = "%s://%s%s" % ( headers_dict[b":scheme"].decode("ascii"), headers_dict[b":authority"].decode("ascii"), headers_dict[b":path"].decode("ascii"), ) headers = [(k, v) for k, v in request["headers"] if not k.startswith(b":")] data = request["data"] # Call out to the app. request = Request(method, url, headers=headers, data=data) response = await self.app(request) # Write the response to the buffer. status_code_bytes = str(response.status_code).encode("ascii") response_headers = [(b":status", status_code_bytes) ] + response.headers.raw self.conn.send_headers(stream_id, response_headers) self.buffer += self.conn.data_to_send() self.return_data[stream_id] = response.content self.send_return_data(stream_id)
def test_make_absolute(): TEST_CASES = [ ("http://base.url", "relative", "http://base.url/relative"), ("http://base.url", ".", "http://base.url/"), ("http://base.url/with_folder", ".", "http://base.url/"), ("http://base.url/with_folder", "./with_dot", "http://base.url/with_dot"), ("http://base.url/with_folder", "..", "http://base.url/"), ("http://base.url/with_folder", "../folder", "http://base.url/folder"), ("http://base.url", "http://whole.url", "http://whole.url/"), ("http://base.url", "https://whole.url", "https://whole.url/"), ("http://base.url", "http://whole.url:987", "http://whole.url:987/"), ("http://base.url", "https://whole.url:987", "https://whole.url:987/"), ("http://base.url", "/", "http://base.url/"), ("http://base.url", "//", ""), ("http://base.url", "//only_this", "http://only_this/"), ("http://base.url", "./..//", "http://base.url/"), ("http://base.url", "./wrong_folder/../good_folder/", "http://base.url/good_folder/"), ] request = Request("GET", "http://base.url") response = Response(status_code=200, request=request) page = Page(response) for base_url, relative_url, expected in TEST_CASES: page._base = base_url assert page.make_absolute(relative_url) == expected, \ f"Absolute url from base_url='{base_url}' and relative_url='{relative_url}' is not '{expected}'"
def _build_response() -> Response: utcnow = datetime.utcnow() response = Response(status_code=201) response.elapsed = timedelta(milliseconds=123) response.request = Request("POST", "http://a.de/b") setattr(response.request, "issued_at", utcnow) # noqa B010 return response
def auth_flow(self, request: Request) -> typing.Generator[Request, Response, None]: try: url, headers, body = self.prepare( str(request.url), request.headers, request.content) yield Request(method=request.method, url=url, headers=headers, data=body) except KeyError as error: description = 'Unsupported token_type: {}'.format(str(error)) raise UnsupportedTokenTypeError(description=description)
def send( self, request: Request, verify: VerifyTypes = None, cert: CertTypes = None, timeout: TimeoutTypes = None, ) -> Response: return Response(200, content=request.read())
def request( # noqa F811 self, *, type_: Any, method: str, url: str, path_params: Dict[str, Any] = None, **kwargs: Any ) -> Any: if path_params is None: path_params = {} url = (self.host or "") + url.format(**path_params) request = Request(method, url, **kwargs) return self.send(request, type_)
def auth_flow( self, request: Request) -> typing.Generator[Request, Response, None]: url, headers, body = self.prepare(request.method, str(request.url), request.headers, request.content) yield Request(method=request.method, url=url, headers=headers, data=body)
def send( self, request: Request, verify: VerifyTypes = None, cert: CertTypes = None, timeout: TimeoutTypes = None, ) -> Response: if request.url.path == "/streaming_response": return Response(200, content=streaming_body(), request=request) elif request.url.path == "/echo_request_body": content = request.read() return Response(200, content=content, request=request) elif request.url.path == "/echo_request_body_streaming": content = b"".join([part for part in request.stream()]) return Response(200, content=content, request=request) else: body = json.dumps({"hello": "world"}).encode() return Response(200, content=body, request=request)
def mock_post(request: httpx.Request, response): url = str(request.url).split('?')[0] if url not in post_apis or request.method != 'POST': return None data = json.loads(request.read().decode()) res = post(url=request.url, json=data, headers=request.headers) response.content = json.loads(res.content.decode('utf-8')) response.status_code = res.status_code return response
def delete_token(self, request: Request) -> Response: assert self.token, "Must obtain GitHub token first" assert request.headers["Accept"] == "application/json" basic_auth_raw = f"{self.config.client_id}:{self.config.client_secret}" basic_auth = base64.b64encode(basic_auth_raw.encode()).decode() assert request.headers["Authorization"] == f"Basic {basic_auth}" assert json.loads(request.read().decode()) == { "access_token": self.token } return Response(status_code=204)
def auth_flow(self, request: Request) -> FlowGen: if self.opportunistic_auth: # add Authorization header before we receive a 401 auth_header = self.generate_request_header(request.url.host) log.debug(f"Preemptive Authorization header: {auth_header}") request.headers['Authorization'] = auth_header response = yield request yield from self.handle_response(response)
def test_raising_connection_error(client, token_method, mock_http_client): request = Request(token_method.http_method, token_method.url) mock_http_client.request.side_effect = ConnectError("Test error", request=request) client.bot.sync_client.http_client = mock_http_client botx_request = client.bot.sync_client.build_request(token_method) with pytest.raises(BotXConnectError): client.bot.sync_client.execute(botx_request)
def test_rule_add_failure(app_client, heksher_client_mock): """ Test that response from upstream is returned to client as expected. """ heksher_client_mock.get_settings.side_effect = HTTPStatusError( "?", request=Request("get", ".."), response=Response(455, content="??")) response = app_client.get("/api/v1/settings") assert response.status_code == 455 assert response.content == b"??"
def generate_page_of_prs(numbers: Iterable[int]) -> Response: """ Create a fake page for the list-pull-requests API. This is used by get_open_pull_requests. """ prs = [{"number": number, "base": {"ref": "main"}} for number in numbers] return Response( status_code=200, content=json.dumps(prs).encode(), request=Request(method="", url=""), )
def sync_auth_flow(self, request: httpx.Request): if self._last_bearer: request.headers["Authorization"] = self._last_bearer response = yield request if response.status_code != 401: return command, env = self._prepare() output = sync_check_output(command, env=env) token = json.loads(output)["status"]["token"] request.headers[ "Authorization"] = self._last_bearer = f"Bearer {token}" yield request