def test_evaluate_error(monkeypatch): monkeypatch.setattr( 'satellite.operations.operations.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) monkeypatch.setattr( 'satellite.operations.operations.evaluate', Mock(side_effect=Exception('test error')), ) mock_emit = Mock() monkeypatch.setattr( 'satellite.operations.pipeline.audit_logs.emit', mock_emit, ) flow = load_flow('http_raw') operation = MockOperation(route_id='route-id', filter_id='filter-id') operation.evaluate(flow, Phase.REQUEST) mock_emit.assert_called_once_with( OperationLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, route_id='route-id', filter_id='filter-id', phase=Phase.REQUEST, operation_name='test-operation', execution_time_ms=ANY, execution_time_ns=ANY, status=OperationStatus.ERROR, error_message='test error', ))
def test_evaluate_ok_nomock(phase, monkeypatch, snapshot): monkeypatch.setattr( 'satellite.operations.operations.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) mock_emit = Mock() monkeypatch.setattr( 'satellite.operations.pipeline.audit_logs.emit', mock_emit, ) flow = load_flow('http_raw') operation = LegitMockOperation(route_id='route-id', filter_id='filter-id') operation.evaluate(flow, phase) snapshot.assert_match(flow.request.get_state(), name='request') mock_emit.assert_called_once_with( OperationLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, route_id='route-id', filter_id='filter-id', phase=phase, operation_name='legit-test-operation', execution_time_ms=ANY, execution_time_ns=ANY, status=OperationStatus.OK, error_message=None, ))
def test_request_redact(monkeypatch, snapshot): route = RouteFactory() rule_entry = RuleEntryFactory() monkeypatch.setattr( 'satellite.vault.vault_handler.ctx.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) monkeypatch.setattr( 'satellite.vault.vault_handler.match_route', Mock(return_value=(route, [rule_entry])), ) monkeypatch.setattr( 'satellite.vault.vault_handler.transform_body', Mock(return_value=('transformed body', [True])), ) emit_audit_log_record = Mock() monkeypatch.setattr( 'satellite.vault.vault_handler.audit_logs.emit', emit_audit_log_record, ) flow = load_flow('http_raw') assert not hasattr(flow, 'request_raw') VaultFlows().request(flow) emit_audit_log_record.assert_called_once_with( audit_logs.VaultRequestAuditLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, method=flow.request.method, uri=flow.request.url, ), ) assert hasattr(flow, 'request_raw') assert flow.request.content != flow.request_raw.content assert flow.request.match_details == { 'route_id': route.id, 'filters': [{ 'id': rule_entry.id, 'operation_applied': True }] } snapshot.assert_match(flow.request.get_state(), 'request') snapshot.assert_match(flow.request_raw.get_state(), 'request_raw')
def test_evaluate_ok(phase, monkeypatch, snapshot): monkeypatch.setattr( 'satellite.operations.operations.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) mock_evaluate = Mock(wraps=lambda code, msg: HttpMessage( url=msg.url, headers=msg.headers, data=msg.data.replace('bar', 'bar_processed'), )) monkeypatch.setattr( 'satellite.operations.operations.evaluate', mock_evaluate, ) mock_emit = Mock() monkeypatch.setattr( 'satellite.operations.pipeline.audit_logs.emit', mock_emit, ) flow = load_flow('http_raw') operation = MockOperation(route_id='route-id', filter_id='filter-id') operation.evaluate(flow, phase) snapshot.assert_match(flow.request.get_state(), name='request') snapshot.assert_match(flow.response.get_state(), name='response') mock_emit.assert_called_once_with( OperationLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, route_id='route-id', filter_id='filter-id', phase=phase, operation_name='test-operation', execution_time_ms=ANY, execution_time_ns=ANY, status=OperationStatus.OK, error_message=None, ))
def test_request_without_redact(monkeypatch): monkeypatch.setattr( 'satellite.vault.vault_handler.ctx.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) monkeypatch.setattr( 'satellite.vault.vault_handler.match_route', Mock(return_value=(None, None)), ) flow = load_flow('http_raw') assert not hasattr(flow, 'request_raw') VaultFlows().request(flow) assert hasattr(flow, 'request_raw') assert flow.request.content == flow.request_raw.content assert not hasattr(flow.request, 'match_details')
def test_operations(monkeypatch): route = RouteFactory() rule_entry = RuleEntryFactory(operations_v2='"some json"') monkeypatch.setattr( 'satellite.vault.vault_handler.ctx.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) monkeypatch.setattr( 'satellite.vault.vault_handler.match_route', Mock(return_value=(route, [rule_entry])), ) monkeypatch.setattr( 'satellite.vault.vault_handler.transform', mock_transform, ) monkeypatch.setattr('satellite.vault.vault_handler.audit_logs.emit', Mock()) build_pipeline = Mock(return_value=Mock(evaluate=mock_transform)) monkeypatch.setattr( 'satellite.vault.vault_handler.build_pipeline', build_pipeline, ) flow = load_flow('http_raw') assert not hasattr(flow, 'request_raw') VaultFlows().request(flow) assert flow.transformed assert flow.request.match_details == { 'route_id': route.id, 'filters': [{ 'id': rule_entry.id, 'operation_applied': True }] }
def test_evaluate(monkeypatch): mock_emit = Mock() monkeypatch.setattr( 'satellite.operations.pipeline.audit_logs.emit', mock_emit, ) monkeypatch.setattr( 'satellite.operations.pipeline.get_proxy_context', Mock( return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, ) ), ) flow = load_flow('http_raw') operation = Mock(operation_name='mock-operation') pipeline = OperationPipeline( route_id='route-id', filter_id='filter-id', operations=[operation], ) pipeline.evaluate(flow, Phase.REQUEST) operation.evaluate.assert_called_once_with(flow, Phase.REQUEST) mock_emit.assert_called_once_with( OperationPipelineEvaluationLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, route_id='route-id', filter_id='filter-id', phase=Phase.REQUEST, execution_time_ms=ANY, execution_time_ns=ANY, operations=['mock-operation'], ) )
def test_response_without_redact(monkeypatch): monkeypatch.setattr( 'satellite.vault.vault_handler.ctx.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) monkeypatch.setattr( 'satellite.vault.vault_handler.match_route', Mock(return_value=(None, None)), ) flow = load_flow('http_raw') assert not hasattr(flow, 'response_raw') flow.server_conn.wfile = Mock(get_log=Mock(return_value=b'abc')) flow.server_conn.rfile = Mock(get_log=Mock(return_value=b'qwerty')) VaultFlows().response(flow) assert hasattr(flow, 'response_raw') assert flow.response.content == flow.response_raw.content assert not hasattr(flow.response, 'match_details')
def run(self): # We need a brand new event loop for child process since we have to # use fork process start method. loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) proxy_logging.configure(self._event_queue) set_context(ProxyContext(mode=self.mode, port=self.port)) self._should_stop = ThreadingEvent() self._command_listener = CommandListener( cmd_channel=self._cmd_channel, cmd_handler=partial( self._handle_command, loop=asyncio.get_event_loop(), ), should_stop=self._should_stop, ) self._command_listener.start() self.master = ProxyMaster(self.mode, self.port) self.master.view.sig_view_add.connect(self._sig_flow_add) self.master.view.sig_view_remove.connect(self._sig_flow_remove) self.master.view.sig_view_update.connect(self._sig_flow_update) blinker.signal('sat_proxy_started').connect(self._sig_proxy_started) self._command_processor = ProxyCommandProcessor(self) signal.signal(signal.SIGINT, signal.SIG_IGN) audit_logs.subscribe(self._sig_audit_log) self.master.run()
def test_response_redact(monkeypatch, snapshot): route = RouteFactory() rule_entry = RuleEntryFactory() monkeypatch.setattr( 'satellite.vault.vault_handler.ctx.get_proxy_context', Mock(return_value=ProxyContext( mode=ProxyMode.FORWARD, port=9099, )), ) monkeypatch.setattr( 'satellite.vault.vault_handler.match_route', Mock(return_value=(route, [rule_entry])), ) monkeypatch.setattr( 'satellite.vault.vault_handler.transform_body', Mock(return_value=('transformed body', [True])), ) emit_audit_log_record = Mock() monkeypatch.setattr( 'satellite.vault.vault_handler.audit_logs.emit', emit_audit_log_record, ) flow = load_flow('http_raw') flow.server_conn.wfile = Mock(get_log=Mock(return_value=b'abc')) flow.server_conn.rfile = Mock(get_log=Mock(return_value=b'qwerty')) assert not hasattr(flow, 'response_raw') VaultFlows().response(flow) emit_audit_log_record.assert_has_calls([ call( audit_logs.VaultTrafficLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, bytes=3, label=audit_logs.TrafficLabel.TO_SERVER, )), call( audit_logs.VaultTrafficLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, bytes=6, label=audit_logs.TrafficLabel.FROM_SERVER, )), call( audit_logs.UpstreamResponseLogRecord( flow_id=flow.id, proxy_mode=ProxyMode.FORWARD, upstream='httpbin.org', status_code=200, )), ]) assert hasattr(flow, 'response_raw') assert flow.response.content != flow.response_raw.content assert flow.response.match_details == { 'route_id': route.id, 'filters': [{ 'id': rule_entry.id, 'operation_applied': True }] } snapshot.assert_match(flow.response.get_state(), 'response') snapshot.assert_match(flow.response_raw.get_state(), 'response_raw')