def test_contemporaneous_requests(self): ''' We're going to create two request-response cycles here: Cycle 1 will begin. Cycle 2 will begin. Cycle 2 will return. Cycle 1 will return. This way, we can prove that the crosstown_traffic created by cycle 1 is not resolved by the return of cycle 2. ''' tp = ThreadPool(maxthreads=20) tp.start() self.addCleanup(tp.stop) log.debug("\n\nStarting the two stream stuff.") request1 = DummyRequest('r1') request1.isSecure = lambda: False request1.content = "Nothing really here." request1.headers['llamas'] = 'dingo' nameSpace.test_case = self hr = HendrixWSGIResource(reactor, tp, wsgi_application) d1 = deferToThreadPool(reactor, tp, hr.render, request1) request2 = DummyRequest('r2') request2.isSecure = lambda: False request2.content = "Nothing really here." request2.headers['llamas'] = 'dingo' d2 = deferToThreadPool(reactor, tp, hr.render, request2) def woah_stop(failure): nameSpace.async_task_was_done.put_nowait(False) nameSpace.second_cycle_complete.put_nowait(False) nameSpace.ready_to_proceed_with_second_cycle.put_nowait(False) d1.addErrback(woah_stop) d2.addErrback(woah_stop) combo_deferred = gatherResults([d1, d2]) def wait_for_queue_resolution(): nameSpace.async_task_was_done.get(True, 3) combo_deferred.addCallback( lambda _: deferToThreadPool(reactor, tp, wait_for_queue_resolution) ) combo_deferred.addCallback( lambda _: self.assertTrue(nameSpace.async_task_was_run) ) return combo_deferred
def test_render_soap_fault(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. If the logged exception is a `SoapFault` its ``to_element`` method is invoked to serialize the fault. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(L.hello())) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(SoapFault) self.assertEqual(1, len(failures)) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Client', 'faultstring': 'Malformed SOAP request'}}}}, element_to_dict(fromstring(''.join(request.written))))
def test_render_exceptions(self): """ `SmsNotificationService.render_POST` logs any exceptions that occur during processing and writes a SOAP fault back to the request. """ def process(*a, **kw): raise ValueError('What is this') service = SmsNotificationService(None, None) service.process = process request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ValueError) self.assertEqual(1, len(failures)) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { str(SOAP_ENV.Fault): { 'faultcode': 'soapenv:Server', 'faultstring': 'What is this'}}}}, element_to_dict(fromstring(''.join(request.written))))
def request_same_or_different_thread_thread(self): hr = HendrixWSGIResource(reactor, self.tp, self.wsgi_thing) request1 = DummyRequest('r1') request1.isSecure = lambda: False request1.content = "llamas" d = deferToThreadPool(reactor, self.tp, hr.render, request1) return d
def request_same_or_different_thread_thread(self): hr = HendrixWSGIResource(reactor, self.tp, self.wsgi_thing) request1 = DummyRequest([b'r1']) request1.isSecure = lambda: False request1.content = b"llamas" request1.client = IPv4Address("TCP", b"50.0.50.0", 5000) d = deferToThreadPool(reactor, self.tp, hr.render, request1) d.addCallback(lambda _: request1.notifyFinish()) return d
def test_success(self): def on_rendered(_): self.assertEqual(['backend reply'], self.request.written) d = _render(self.resource, self.request).addCallback(on_rendered) callback_request = DummyRequest(['']) callback_request.content = StringIO('backend reply') self.resource.factory.requests.values()[0].notify(callback_request) return d
def test_post_returns_internal_server_error(self, mock_update_recovery_code): mock_update_recovery_code.return_value = defer.fail(Exception) request = DummyRequest(['/backup-account']) request.method = 'POST' request.content = MagicMock() request.content.getvalue.return_value = '{"email": "*****@*****.**"}' d = self.web.get(request) def assert_successful_response(_): self.assertEqual(500, request.responseCode) d.addCallback(assert_successful_response) return d
def test_post_returns_successfully(self, mock_update_recovery_code): mock_update_recovery_code.return_value = defer.succeed("Success") request = DummyRequest(['/backup-account']) request.method = 'POST' request.content = MagicMock() request.content.getvalue.return_value = '{"email": "*****@*****.**"}' d = self.web.get(request) def assert_successful_response(_): self.assertEqual(204, request.responseCode) d.addCallback(assert_successful_response) return d
def test_sends_feedback_to_leap_web(self): request = DummyRequest(['/feedback']) request.method = 'POST' content = mock() when(content).read().thenReturn(json.dumps({'feedback': 'Pixelated is awesome!'})) request.content = content d = self.web.get(request) def assert_posted_feedback_to_leap_web(_): verify(self.feedback_service).open_ticket('Pixelated is awesome!') d.addCallback(assert_posted_feedback_to_leap_web) return d
def test_render_invalid_xml(self): """ `SmsNotificationService.render_POST` does not accept invalid XML body content. """ service = SmsNotificationService(None, None) request = DummyRequest([]) request.content = StringIO('sup') d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.INTERNAL_SERVER_ERROR, request.responseCode) failures = self.flushLoggedErrors(ParseError) self.assertEqual(1, len(failures))
def test_render_PUT_should_store_draft_with_attachments(self, mock_register): request = DummyRequest([]) request.method = 'PUT' request.content = mock() when(request.content).read().thenReturn('{"attachments": [{"ident": "some fake attachment id"}]}') when(self.mail_service).attachment('some fake attachment id').thenReturn(defer.succeed({'content': mock()})) mails_resource = MailsResource(self.services_factory) web = DummySite(mails_resource) d = web.get(request) def assert_response(_): verify(self.mail_service).attachment('some fake attachment id') d.addCallback(assert_response) return d
def test_bad_status_codes_cause_no_go_in_wsgi_response(self): self.no_go_status_codes = [404, '6xx'] request = DummyRequest('r1') request.isSecure = lambda: False request.content = "llamas" finished = request.notifyFinish() self.resource.render(request) # This must wait until the WSGI response is closed. finished.addCallback( lambda _: self.assertFalse( self.nameSpace.async_task_was_run ) )
def test_should_unauthorize_child_resource_non_ajax_POST_requests_when_csrf_input_mismatch(self): request = DummyRequest(['mails']) request.method = 'POST' request.addArg('csrftoken', 'some csrf token') mock_content = MagicMock() mock_content.read = MagicMock(return_value={}) request.content = mock_content request.getCookie = MagicMock(return_value='mismatched csrf token') d = self.web.get(request) def assert_unauthorized(_): self.assertEqual(401, request.responseCode) self.assertEqual("Unauthorized!", request.written[0]) d.addCallback(assert_unauthorized) return d
def test_render_POST_should_archive_mails(self): request = DummyRequest(["/mails/archive"]) request.method = "POST" content = mock() when(content).read().thenReturn(json.dumps({"idents": ["1", "2"]})) when(self.mail_service).archive_mail("1").thenReturn(defer.Deferred()) when(self.mail_service).archive_mail("2").thenReturn(defer.Deferred()) request.content = content d = self.web.get(request) def assert_response(_): verify(self.mail_service).archive_mail("1") verify(self.mail_service).archive_mail("2") d.addCallback(assert_response) return d
def test_render(self): """ `SmsNotificationService.render_POST` parses a SOAP request and dispatches it to `SmsNotificationService.process` for processing. """ service = SmsNotificationService(None, None) service.process = lambda *a, **kw: L.done() request = DummyRequest([]) request.content = StringIO(tostring(soap_envelope('hello'))) d = request.notifyFinish() service.render_POST(request) self.successResultOf(d) self.assertEqual(http.OK, request.responseCode) self.assertEqual( {str(SOAP_ENV.Envelope): { str(SOAP_ENV.Body): { 'done': None}}}, element_to_dict(fromstring(''.join(request.written))))
def test_render_POST_should_archive_mails(self): request = DummyRequest(['/mails/archive']) request.method = 'POST' idents = ['1', '2'] content = mock() when(content).read().thenReturn(json.dumps({'idents': ['1', '2']})) when(self.mail_service).archive_mail('1').thenReturn(defer.succeed(None)) when(self.mail_service).archive_mail('2').thenReturn(defer.succeed(None)) request.content = content d = self.web.get(request) def assert_response(_): verify(self.mail_service).archive_mail('1') verify(self.mail_service).archive_mail('2') d.addCallback(assert_response) return d
def test_post_attachment_fails(self, mock_fields): request = DummyRequest(['/attachment']) request.method = 'POST' request.content = 'mocked' _file = MagicMock() _file.value = 'some mocked value' _file.type = 'some mocked type' mock_fields.return_value = {'attachment': _file} when(self.mail_service).save_attachment('some mocked value', 'some mocked type').thenReturn(defer.fail(Exception)) d = self.web.get(request) def assert_response(_): self.assertEqual(500, request.code) self.assertFalse(request.responseHeaders.hasHeader('Location'.lower())) self.assertIn("message", json.loads(request.written[0])) verify(self.mail_service).save_attachment('some mocked value', 'some mocked type') d.addCallback(assert_response) return d
def test_render_POST_should_send_email_with_attachments(self, mock_register): request = DummyRequest([]) request.method = 'POST' request.content = mock() when(request.content).read().thenReturn('{"attachments": [{"ident": "some fake attachment id"}]}') when(self.mail_service).attachment('some fake attachment id').thenReturn(defer.succeed({"content": "some content"})) as_dictable = mock() when(as_dictable).as_dict().thenReturn({}) when(self.mail_service).send_mail({"attachments": [{"ident": "some fake attachment id", "raw": "some content"}]})\ .thenReturn(defer.succeed(as_dictable)) mails_resource = MailsResource(self.services_factory) web = DummySite(mails_resource) d = web.get(request) def assert_response(_): verify(self.mail_service).attachment('some fake attachment id') verify(self.mail_service).send_mail({"attachments": [{"ident": "some fake attachment id", "raw": "some content"}]}) d.addCallback(assert_response) return d
def test_post_updates_recovery_code(self, mock_account_recovery_init, mock_language): mock_language.return_value = 'pt-BR' mock_account_recovery = MagicMock() mock_account_recovery_init.return_value = mock_account_recovery mock_account_recovery.update_recovery_code.return_value = defer.succeed("Success") request = DummyRequest(['/backup-account']) request.method = 'POST' request.content = MagicMock() request.content.getvalue.return_value = '{"email": "*****@*****.**"}' d = self.web.get(request) def assert_update_recovery_code_called(_): mock_account_recovery_init.assert_called_with( self.resource._authenticator.bonafide_session, self.resource.soledad(request), self.resource._service(request, '_leap_session').smtp_config, self.resource._get_backup_email(request), self.leap_provider.server_name, language='pt-BR') mock_account_recovery.update_recovery_code.assert_called() d.addCallback(assert_update_recovery_code_called) return d
def test_post_new_attachment(self, mock_fields): request = DummyRequest(['/attachment']) request.method = 'POST' request.content = 'mocked' attachment_id = 'B5B4ED80AC3B894523D72E375DACAA2FC6606C18EDF680FE95903086C8B5E14A' _file = MagicMock() _file.value = 'some mocked value' _file.type = 'some mocked type' _file.filename = 'filename.txt' mock_fields.return_value = {'attachment': _file} when(self.mail_service).save_attachment('some mocked value', 'some mocked type').thenReturn(defer.succeed(attachment_id)) d = self.web.get(request) def assert_response(_): self.assertEqual(201, request.code) self.assertEqual('/attachment/%s' % attachment_id, request.responseHeaders.getRawHeaders("location")[0]) response_json = {'ident': attachment_id, 'content-type': 'some mocked type', 'name': 'filename.txt', 'size': 17, 'encoding': 'base64'} self.assertEqual(response_json, json.loads(request.written[0])) verify(self.mail_service).save_attachment('some mocked value', 'some mocked type') d.addCallback(assert_response) return d
def forge_request(uri=b'https://www.globaleaks.org/', headers=None, body='', client_addr=None, method=b'GET'): """ Creates a twisted.web.Request compliant request that is from an external IP address. """ if headers is None: headers = {} _, host, path, query, frag = urlsplit(uri) x = host.split(b':') if len(x) > 1: port = int(x[1]) else: port = 80 request = DummyRequest([b'']) request.tid = 1 request.method = method request.uri = uri request.path = path request._serverName = host request.code = 200 request.client_ip = b'127.0.0.1' request.client_proto = b'https' request.client_using_tor = False def getResponseBody(): # Ugh, hack. Twisted returns this all as bytes, and we want it as str if isinstance(request.written[0], binary_type): return b''.join(request.written) else: return ''.join(request.written) request.getResponseBody = getResponseBody if client_addr is None: request.client = IPv4Address('TCP', b'1.2.3.4', 12345) else: request.client = client_addr def getHost(): return IPv4Address('TCP', b'127.0.0.1', port) request.getHost = getHost def notifyFinish(): return Deferred() request.notifyFinish = notifyFinish request.requestHeaders.setRawHeaders('host', [b'127.0.0.1']) request.requestHeaders.setRawHeaders('user-agent', [b'NSA Agent']) for k, v in headers.items(): request.requestHeaders.setRawHeaders(k, [v]) request.headers = request.getAllHeaders() class fakeBody(object): def read(self): if isinstance(body, dict): ret = json.dumps(body) else: ret = body if isinstance(ret, text_type): ret = ret.encode('utf-8') return ret def close(self): pass request.content = fakeBody() return request
def test_contemporaneous_requests(): ''' We're going to create two request-response cycles here: Cycle 1 will begin. Cycle 2 will begin. Cycle 2 will return. Cycle 1 will return. This way, we can prove that the crosstown_traffic created by cycle 1 is not resolved by the return of cycle 2. ''' tp = ThreadPool(maxthreads=20) tp.start() log.debug("\n\nStarting the two stream stuff.") request1 = DummyRequest([b'r1']) request1.isSecure = lambda: False request1.content = "Nothing really here." request1.requestHeaders.addRawHeader('llamas', 'dingo') request1.client = IPv4Address("TCP", b"50.0.50.0", 5000) hr = HendrixWSGIResource(reactor, tp, wsgi_application) yield deferToThreadPool(reactor, tp, hr.render, request1) request2 = DummyRequest([b'r2']) request2.isSecure = lambda: False request2.content = b"Nothing really here." request2.requestHeaders.addRawHeader('llamas', 'dingo') request2.client = IPv4Address("TCP", b"100.0.50.0", 5000) yield deferToThreadPool(reactor, tp, hr.render, request2) # def woah_stop(failure): # nameSpace.async_task_was_done.put_nowait(False) # nameSpace.second_cycle_complete.put_nowait(False) # nameSpace.ready_to_proceed_with_second_cycle.put_nowait(False) # # d1.addErrback(woah_stop) # d2.addErrback(woah_stop) # combo_deferred = gatherResults([d1, d2]) # yield d1 # yield d2 # combo_deferred = DeferredList([d1, d2]) def wait_for_queue_resolution(): nameSpace.async_task_was_done.get(True, 3) # combo_deferred.addCallback( # lambda _: # ) # yield deferToThreadPool(reactor, tp, wait_for_queue_resolution) # combo_deferred.addCallback( # lambda _: # ) assert nameSpace.async_task_was_run tp.stop()
def forge_request(uri='https://www.globaleaks.org/', headers=None, body='', client_addr=None, method='GET', handler_cls=None, attached_file={}): """ Creates a twisted.web.Request compliant request that is from an external IP address. """ if headers is None: headers = {} _, host, path, query, frag = urlparse.urlsplit(uri) x = host.split(':') if len(x) > 1: port = int(x[1]) else: port = 80 request = DummyRequest(['']) request.tid = 1 request.method = method request.uri = uri request.path = path request._serverName = bytes(host) request.code = 200 request.client_ip = '127.0.0.1' request.client_proto = 'https' request.client_using_tor = False def getResponseBody(): return ''.join(request.written) request.getResponseBody = getResponseBody if client_addr is None: request.client = IPv4Address('TCP', '1.2.3.4', 12345) else: request.client = client_addr def getHost(): return IPv4Address('TCP', '127.0.0.1', port) request.getHost = getHost def notifyFinish(): return Deferred() request.notifyFinish = notifyFinish request.requestHeaders.setRawHeaders('host', ['127.0.0.1']) for k, v in headers.items(): request.requestHeaders.setRawHeaders(bytes(k), [bytes(v)]) request.headers = request.getAllHeaders() request.args = {} if attached_file is not None: request.args = {'file': [attached_file]} class fakeBody(object): def read(self): if isinstance(body, dict): return json.dumps(body) else: return body def close(self): pass request.content = fakeBody() return request
def forge_request(uri=b'https://www.globaleaks.org/', headers=None, body='', client_addr=None, method=b'GET'): """ Creates a twisted.web.Request compliant request that is from an external IP address. """ if headers is None: headers = {} _, host, path, query, frag = urlsplit(uri) x = host.split(b':') if len(x) > 1: port = int(x[1]) else: port = 80 request = DummyRequest([b'']) request.tid = 1 request.method = method request.uri = uri request.path = path request._serverName = host request.code = 200 request.client_ip = b'127.0.0.1' request.client_proto = b'https' request.client_using_tor = False def getResponseBody(): # Ugh, hack. Twisted returns this all as bytes, and we want it as str if isinstance(request.written[0], binary_type): return b''.join(request.written) else: return ''.join(request.written) request.getResponseBody = getResponseBody if client_addr is None: request.client = IPv4Address('TCP', b'1.2.3.4', 12345) else: request.client = client_addr def getHost(): return IPv4Address('TCP', b'127.0.0.1', port) request.getHost = getHost def notifyFinish(): return Deferred() request.notifyFinish = notifyFinish request.requestHeaders.setRawHeaders('host', [b'127.0.0.1']) request.requestHeaders.setRawHeaders('user-agent', [b'NSA Agent']) for k, v in headers.items(): request.requestHeaders.setRawHeaders(k, [v]) request.headers = request.getAllHeaders() class fakeBody(object): def read(self): if isinstance(body, dict): ret = json.dumps(body) else: ret = body if isinstance(ret, text_type): ret = ret.encode('utf-8') return ret def close(self): pass request.content = fakeBody() return request
def request(self, jbody=None, user_id=None, role=None, headers=None, body='', path=None, remote_ip='0.0.0.0', method='MOCK', handler_cls=None, attached_file={}, kwargs={}): """ Constructs a handler for preforming mock requests using the bag of params described below. Args: jbody: The body of the request as a dict (it will be automatically converted to string) body: The body of the request as a string user_id: when simulating authentication the session should be bound to a certain user_id. role: when simulating authentication the session should be bound to a certain role. method: HTTP method, e.g. "GET" or "POST" headers: Dict of headers to pass on the request remote_ip: If a particular remote_ip should be set. handler_cls: The type of handler that will respond to the request. If this is not set self._handler is used. attached_file: A dict to place in the request.args.files obj """ if jbody and not body: body = json.dumps(jbody) elif body and jbody: raise ValueError('jbody and body in conflict') if handler_cls is None: handler_cls = self._handler request = DummyRequest(['']) def getResponseBody(): return ''.join(request.written) request.path = '' request.code = 200 request.language = 'en' request.client_ip = '127.0.0.1' request.client_proto = 'https' request.client_using_tor = False request.getResponseBody = getResponseBody request.client = IPv4Address('TCP', '1.2.3.4', 12345) request.args = {} if attached_file is not None: request.args = {'file': [attached_file]} if headers is not None: for k, v in headers.iteritems(): request.requestHeaders.setRawHeaders(bytes(k), [bytes(v)]) request.headers = request.getAllHeaders() from globaleaks.rest import api x = api.APIResourceWrapper() x.preprocess(request) if path is not None: if not path.startswith('/'): raise ValueError('Must pass a valid url path') request.path = path class fakeBody(object): def read(self): return body def close(self): pass request.content = fakeBody() from globaleaks.rest.api import decorate_method if not getattr(handler_cls, 'decorated', False): for method in ['get', 'post', 'put', 'delete']: if getattr(handler_cls, method, None) is not None: decorate_method(handler_cls, method) handler_cls.decorated = True handler = handler_cls(request, **kwargs) if user_id is None and role is not None: if role == 'admin': user_id = self.dummyAdminUser['id'] elif role == 'receiver': user_id = self.dummyReceiverUser_1['id'] elif role == 'custodian': user_id = self.dummyCustodianUser['id'] if role is not None: session = GLSession(user_id, role, 'enabled') handler.request.headers['x-session'] = session.id return handler
def test_contemporaneous_requests(): ''' We're going to create two request-response cycles here: Cycle 1 will begin. Cycle 2 will begin. Cycle 2 will return. Cycle 1 will return. This way, we can prove that the crosstown_traffic created by cycle 1 is not resolved by the return of cycle 2. ''' tp = ThreadPool(maxthreads=20) tp.start() log.debug("\n\nStarting the two stream stuff.") request1 = DummyRequest([b'r1']) request1.isSecure = lambda: False request1.content = "Nothing really here." request1.requestHeaders.addRawHeader('llamas', 'dingo') request1.client = IPv4Address("TCP", b"50.0.50.0", 5000) hr = HendrixWSGIResource(reactor, tp, wsgi_application) yield deferToThreadPool(reactor, tp, hr.render, request1) request2 = DummyRequest([b'r2']) request2.isSecure = lambda: False request2.content = b"Nothing really here." request2.requestHeaders.addRawHeader('llamas', 'dingo') request2.client = IPv4Address("TCP", b"100.0.50.0", 5000) yield deferToThreadPool(reactor, tp, hr.render, request2) # def woah_stop(failure): # nameSpace.async_task_was_done.put_nowait(False) # nameSpace.second_cycle_complete.put_nowait(False) # nameSpace.ready_to_proceed_with_second_cycle.put_nowait(False) # # d1.addErrback(woah_stop) # d2.addErrback(woah_stop) # combo_deferred = gatherResults([d1, d2]) # yield d1 # yield d2 # combo_deferred = DeferredList([d1, d2]) def wait_for_queue_resolution(): nameSpace.async_task_was_done.get(True, 3) # combo_deferred.addCallback( # lambda _: # ) # yield deferToThreadPool(reactor, tp, wait_for_queue_resolution) # combo_deferred.addCallback( # lambda _: # ) assert nameSpace.async_task_was_run tp.stop()