summaryrefslogtreecommitdiff
path: root/service/test/unit
diff options
context:
space:
mode:
authorJon Newson <jon_newson@ieee.org>2016-02-26 16:20:59 +1100
committerJon Newson <jon_newson@ieee.org>2016-02-26 16:20:59 +1100
commit05f4e2ca2d64eaba23c87df4d2e2cc9e09bba6de (patch)
tree50b2ccf6454f31a3f6bceaa997a5e2abbcb91a80 /service/test/unit
parent52467b9aef76c9aac2f250478befd3afb7b6aabd (diff)
parentdbb434b56e6b161a3b851ae6a81f96dff14a29da (diff)
Merge branch 'master' of https://github.com/pixelated/pixelated-user-agent
# By Felix Hammerl (5) and others # Via NavaL * 'master' of https://github.com/pixelated/pixelated-user-agent: serving the client directly, as the current dependency on proxy strips out xsrf cookies -fixing functional test only adding feature resource in root_resource test -- fixing build changed logout to post Issue #612 Backend and frontend protection against csrf attacks: - root resources changes the csrf token cookie everytime it is loaded, in particular during the intestitial load during login - it will also add that cookie on single user mode - initialize will still load all resources - but they you cant access them if the csrf token do not match - all ajax calls needs to add the token to the header - non ajax get requests do not need xsrf token validation - non ajax post will have to send the token in as a form input or in the content Consolidate stylesheets Remove unused font and stylesheetgit s Create a new deferred for all IMAPAccount calls Clean up jshintrc Recreate session on soledad problems issue #617: Remove old html whitelister Issue #617: Sanitize received content
Diffstat (limited to 'service/test/unit')
-rw-r--r--service/test/unit/bitmask_libraries/test_session.py12
-rw-r--r--service/test/unit/config/test_leap.py38
-rw-r--r--service/test/unit/resources/test_logout_resources.py8
-rw-r--r--service/test/unit/resources/test_root_resource.py83
4 files changed, 139 insertions, 2 deletions
diff --git a/service/test/unit/bitmask_libraries/test_session.py b/service/test/unit/bitmask_libraries/test_session.py
index a41cb805..aad2cac2 100644
--- a/service/test/unit/bitmask_libraries/test_session.py
+++ b/service/test/unit/bitmask_libraries/test_session.py
@@ -133,6 +133,16 @@ class SessionTest(AbstractLeapTest):
self.assertTrue(session.fresh_account)
@patch('pixelated.bitmask_libraries.session.register')
+ def test_closed_session_not_reused(self, _):
+ session = self._create_session()
+ SessionCache.remember_session('somekey', session)
+ session._is_closed = True
+
+ result = SessionCache.lookup_session('somekey')
+
+ self.assertIsNone(result)
+
+ @patch('pixelated.bitmask_libraries.session.register')
def test_session_does_not_set_status_fresh_for_unkown_emails(self, _):
session = self._create_session()
self.provider.address_for.return_value = 'someone@somedomain.tld'
@@ -150,7 +160,7 @@ class SessionTest(AbstractLeapTest):
with patch('pixelated.bitmask_libraries.session.reactor.callFromThread', new=_execute_func) as _:
with patch.object(LeapSession, '_create_incoming_mail_fetcher', return_value=mailFetcherMock) as _:
session = self._create_session()
- session._has_been_synced = True
+ session._has_been_initially_synced = True
yield session.initial_sync()
self.assertFalse(mailFetcherMock.startService.called)
diff --git a/service/test/unit/config/test_leap.py b/service/test/unit/config/test_leap.py
new file mode 100644
index 00000000..6b34d717
--- /dev/null
+++ b/service/test/unit/config/test_leap.py
@@ -0,0 +1,38 @@
+from leap.soledad.common.errors import InvalidAuthTokenError
+from mock import MagicMock, patch
+from twisted.trial import unittest
+from twisted.internet import defer
+from pixelated.config.leap import authenticate_user
+
+
+class TestAuth(unittest.TestCase):
+
+ @patch('pixelated.config.leap.LeapSessionFactory')
+ @defer.inlineCallbacks
+ def test_authenticate_user_calls_initinal_sync(self, session_factory__ctor_mock):
+ session_factory_mock = session_factory__ctor_mock.return_value
+ provider_mock = MagicMock()
+ auth_mock = MagicMock()
+ session = MagicMock()
+
+ session_factory_mock.create.return_value = session
+
+ yield authenticate_user(provider_mock, 'username', 'password', auth=auth_mock)
+
+ session.initial_sync.assert_called_with()
+
+ @patch('pixelated.config.leap.LeapSessionFactory')
+ @defer.inlineCallbacks
+ def test_authenticate_user_calls_initial_sync_a_second_time_if_invalid_auth_exception_is_raised(self, session_factory__ctor_mock):
+ session_factory_mock = session_factory__ctor_mock.return_value
+ provider_mock = MagicMock()
+ auth_mock = MagicMock()
+ session = MagicMock()
+
+ session.initial_sync.side_effect = [InvalidAuthTokenError, defer.succeed(None)]
+ session_factory_mock.create.return_value = session
+
+ yield authenticate_user(provider_mock, 'username', 'password', auth=auth_mock)
+
+ session.close.assert_called_with()
+ self.assertEqual(2, session.initial_sync.call_count)
diff --git a/service/test/unit/resources/test_logout_resources.py b/service/test/unit/resources/test_logout_resources.py
index 48cf9db9..6246eeb9 100644
--- a/service/test/unit/resources/test_logout_resources.py
+++ b/service/test/unit/resources/test_logout_resources.py
@@ -1,6 +1,7 @@
from mock import patch
from mockito import mock, verify
from twisted.trial import unittest
+from twisted.web.error import UnsupportedMethod
from twisted.web.test.requesthelper import DummyRequest
from pixelated.resources.logout_resource import LogoutResource
@@ -16,6 +17,7 @@ class TestLogoutResource(unittest.TestCase):
@patch('twisted.web.util.redirectTo')
def test_logout(self, mock_redirect):
request = DummyRequest(['/logout'])
+ request.method = 'POST'
mock_redirect.return_value = 'haha'
@@ -29,3 +31,9 @@ class TestLogoutResource(unittest.TestCase):
d.addCallback(expire_session_and_redirect)
return d
+
+ def test_get_is_not_supported_for_logout(self):
+ request = DummyRequest(['/logout'])
+ request.method = 'GET'
+
+ self.assertRaises(UnsupportedMethod, self.web.get, request)
diff --git a/service/test/unit/resources/test_root_resource.py b/service/test/unit/resources/test_root_resource.py
index 3b0846ee..cc052d8b 100644
--- a/service/test/unit/resources/test_root_resource.py
+++ b/service/test/unit/resources/test_root_resource.py
@@ -1,11 +1,14 @@
import unittest
import re
+
+from mock import MagicMock, patch
from mockito import mock, when, any as ANY
from pixelated.application import UserAgentMode
+from pixelated.resources.features_resource import FeaturesResource
from test.unit.resources import DummySite
from twisted.web.test.requesthelper import DummyRequest
-from pixelated.resources.root_resource import RootResource
+from pixelated.resources.root_resource import RootResource, MODE_STARTUP, MODE_RUNNING
class TestRootResource(unittest.TestCase):
@@ -25,9 +28,11 @@ class TestRootResource(unittest.TestCase):
root_resource._html_template = "<html><head><title>$account_email</title></head></html>"
root_resource._mode = root_resource
self.web = DummySite(root_resource)
+ self.root_resource = root_resource
def test_render_GET_should_template_account_email(self):
request = DummyRequest([''])
+ request.addCookie = lambda key, value: 'stubbed'
d = self.web.get(request)
@@ -38,3 +43,79 @@ class TestRootResource(unittest.TestCase):
d.addCallback(assert_response)
return d
+
+ def _test_should_renew_xsrf_cookie(self):
+ request = DummyRequest([''])
+ request.addCookie = MagicMock()
+ generated_csrf_token = 'csrf_token'
+ mock_sha = MagicMock()
+ mock_sha.hexdigest = MagicMock(return_value=generated_csrf_token)
+
+ with patch('hashlib.sha256', return_value=mock_sha):
+ d = self.web.get(request)
+
+ def assert_csrf_cookie(_):
+ request.addCookie.assert_called_once_with('XSRF-TOKEN', generated_csrf_token)
+
+ d.addCallback(assert_csrf_cookie)
+ return d
+
+ def test_should_renew_xsrf_cookie_on_startup_mode(self):
+ self.root_resource._mode = MODE_STARTUP
+ self._test_should_renew_xsrf_cookie()
+
+ def test_should_renew_xsrf_cookie_on_running_mode(self):
+ self.root_resource._mode = MODE_RUNNING
+ self._test_should_renew_xsrf_cookie()
+
+ def _mock_ajax_csrf(self, request, csrf_token):
+ request.headers['x-requested-with'] = 'XMLHttpRequest'
+ request.headers['x-xsrf-token'] = csrf_token
+
+ def test_should_unauthorize_child_resource_ajax_requests_when_csrf_mismatch(self):
+ request = DummyRequest(['/child'])
+ self._mock_ajax_csrf(request, 'stubbed csrf token')
+
+ 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_should_authorize_child_resource_non_ajax_GET_requests(self):
+ request = DummyRequest(['features'])
+
+ request.getCookie = MagicMock(return_value='irrelevant -- stubbed')
+ self.root_resource._child_resources.add('features', FeaturesResource())
+
+ d = self.web.get(request)
+
+ def assert_unauthorized(_):
+ self.assertEqual(200, request.code)
+
+ d.addCallback(assert_unauthorized)
+ return d
+
+ 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