def dss_notification(): body = app.current_request.json_body bundle_uuid = body['match']['bundle_uuid'] bundle_version = body['match']['bundle_version'] subscription_id = body['subscription_id'] event_type = body['event_type'] config = MatrixInfraConfig() hmac_secret_key = config.dss_subscription_hmac_secret_key.encode() HTTPSignatureAuth.verify( requests.Request(url="http://host/dss/notification", method=app.current_request.method, headers=app.current_request.headers), key_resolver=lambda key_id, algorithm: hmac_secret_key) payload = { 'bundle_uuid': bundle_uuid, 'bundle_version': bundle_version, 'event_type': event_type, } queue_url = config.notification_q_url SQSHandler().add_message_to_queue(queue_url, payload) return chalice.Response( status_code=requests.codes.ok, body=f"Received notification from subscription {subscription_id}: " f"{event_type} {bundle_uuid}.{bundle_version}")
def verify(current_request: chalice.app.Request) -> str: try: current_request.headers['authorization'] except KeyError as e: logger.warning('Missing authorization header: ', exc_info=e) chalice.UnauthorizedError('Not Authorized') base_url = current_request.headers['host'] path = current_request.context['resourcePath'] endpoint = f'{base_url}{path}' method = current_request.context['httpMethod'] headers = current_request.headers _key_id: Optional[str] = None def key_resolver(*, key_id, algorithm): require(algorithm == 'hmac-sha256', algorithm) key, _ = aws.get_hmac_key_and_id_cached(key_id) key = key.encode() # Since HTTPSignatureAuth.verify doesn't return anything we need to # extract the key ID in this round-about way. nonlocal _key_id _key_id = key_id return key try: HTTPSignatureAuth.verify(requests.Request(method, endpoint, headers), key_resolver=key_resolver) except BaseException as e: logger.warning('Exception while validating HMAC: ', exc_info=e) raise chalice.UnauthorizedError('Invalid authorization credentials') else: assert _key_id is not None return _key_id
def do_POST(self): length = int(self.headers['content-length']) attempt = int(self.headers[attempt_header_name]) payload = json.loads(self.rfile.read(length).decode()) verify = payload['verify'] if verify: HTTPSignatureAuth.verify( requests.Request("POST", self.path, self.headers), key_resolver=lambda key_id, algorithm: self.hmac_secret_key) try: HTTPSignatureAuth.verify(requests.Request( "POST", self.path, self.headers), key_resolver=lambda key_id, algorithm: self.hmac_secret_key[::-1]) except AssertionError: pass else: raise AssertionError("Expected AssertionError") responses = payload['responses'] delay, status = responses[attempt if attempt < len(responses) else -1] self.send_response(status) if delay: self.send_header("Content-length", len(self.response_body)) self.end_headers() time.sleep(delay) # Write a lot of data to force the detection of a client disconnect. The connection is to the loopback # interface so this shouldn't matter much performance-wise. When the disconnect is detected, # the execptions raised range from the expected EPIPE to the exotic 'OSError: [Errno 41] Protocol wrong # type for socket'. We don't care which exception is raised as long as it prevents the request being # recorded as a success. try: self.wfile.write(self.response_body) self.wfile.flush() except OSError: logger.info( "An expected exception occurred while sending response to client:", exc_info=True) return else: self.send_header("Content-length", 0) self.end_headers() if status == 200: notification_id = payload['notification_id'] logger.info("Received notification_id %s", notification_id) self.actual_receptions.append(notification_id)
def send(self, request, *args, **kwargs): def key_resolver(key_id, algorithm): if "pubkey" in request.headers: return base64.b64decode(request.headers["pubkey"]) return hmac_secret HTTPSignatureAuth.verify(request, key_resolver=key_resolver, scheme=request.headers.get( "sigScheme", "Authorization")) if "expectSig" in request.headers: self.testcase.assertEqual( request.headers["expectSig"], HTTPSignatureAuth.get_sig_struct(request)["signature"]) response = requests.Response() response.status_code = requests.codes.ok response.url = request.url return response
def sign_view(request): try: HTTPSignatureAuth.verify(request, key_resolver=key_resolver) except (AssertionError, ClientSecret.DoesNotExist): raise PermissionDenied tx_params = request.data try: account = BlockchainAccount.objects.get(address=tx_params.pop('from')) except BlockchainAccount.DoesNotExist: raise PermissionDenied if account.network_type == NetworkType.ETHEREUM_LIKE: signed_tx = Web3().eth.account.sign_transaction( tx_params, account.private_key) raw_hex_tx = signed_tx.rawTransaction.hex() return JsonResponse({'signed_tx': raw_hex_tx}) elif account.network_type == NetworkType.BINANCE_CHAIN: raise PermissionDenied
def my_handle(self, method): global recieved_notification if "notification_test_pass_with_auth" in self.path: code = 200 HTTPSignatureAuth.verify(requests.Request(method, self.path, self.headers), key_resolver=lambda key_id, algorithm: self.hmac_secret_key.encode()) if "notification_test_pass" in self.path: code = 200 elif "notification_test_fail" in self.path: code = 400 else: return self._generic_handle() size = int(self.headers.get('Content-Length', 0)) body = self.rfile.read(size) try: recieved_notification = json.loads(body) except Exception as e: recieved_notification = str(e) self.send_response(code) self.send_header("Content-Length", 0) self.end_headers()
def verify(current_request): try: current_request.headers['authorization'] except KeyError as e: logger.warning('Missing authorization header: ', exc_info=e) chalice.UnauthorizedError('Not Authorized') base_url = current_request.headers['host'] path = current_request.context['resourcePath'] endpoint = f'{base_url}{path}' method = current_request.context['httpMethod'] headers = current_request.headers def key_resolver(key_id, algorithm): require(algorithm == 'hmac-sha256', algorithm) key, _ = aws.get_hmac_key_and_id_cached(key_id) return key.encode() try: HTTPSignatureAuth.verify(requests.Request(method, endpoint, headers), key_resolver=key_resolver) except BaseException as e: logger.warning('Exception while validating HMAC: ', exc_info=e) raise chalice.UnauthorizedError('Invalid authorization credentials')