summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/pixelated/authentication.py36
-rw-r--r--service/pixelated/config/leap.py13
-rw-r--r--service/test/support/integration/app_test_client.py3
-rw-r--r--service/test/support/integration/multi_user_client.py2
-rw-r--r--service/test/unit/bitmask_libraries/test_smtp_client_certificate.py2
-rw-r--r--service/test/unit/test_authentication.py42
6 files changed, 70 insertions, 28 deletions
diff --git a/service/pixelated/authentication.py b/service/pixelated/authentication.py
index c9961476..a8326fb9 100644
--- a/service/pixelated/authentication.py
+++ b/service/pixelated/authentication.py
@@ -1,29 +1,33 @@
import re
+from pixelated.config.leap import authenticate
+from leap.bitmask.bonafide._srp import SRPAuthError
-
-class Authentication(object):
- def __init__(self, username, token, uuid, session_id, user_attributes):
- self.username = username
- self.token = token
- self.uuid = uuid
- self.session_id = session_id
- self._user_attributes = user_attributes
-
- def is_admin(self):
- return self._user_attributes.get('is_admin', False)
+from twisted.cred.error import UnauthorizedLogin
+from twisted.internet.defer import inlineCallbacks
class Authenticator(object):
- def __init__(self, domain):
- self.domain = domain
+ def __init__(self, leap_provider):
+ self._leap_provider = leap_provider
+ self.domain = leap_provider.server_name
+ @inlineCallbacks
def authenticate(self, username, password):
- self.username = self.validate_username(username)
- self.srp_auth(username, password)
+ if self.validate_username(username):
+ yield self._srp_auth(username, password)
+ else:
+ raise UnauthorizedLogin()
+
+ @inlineCallbacks
+ def _srp_auth(self, username, password):
+ try:
+ auth = yield authenticate(self._leap_provider, username, password)
+ except SRPAuthError:
+ raise UnauthorizedLogin()
def validate_username(self, username):
if '@' not in username:
- return True
+ return True
extracted_username = self.extract_username(username)
return self.username_with_domain(extracted_username) == username
diff --git a/service/pixelated/config/leap.py b/service/pixelated/config/leap.py
index 5dbfe21b..b86b756e 100644
--- a/service/pixelated/config/leap.py
+++ b/service/pixelated/config/leap.py
@@ -13,7 +13,6 @@ from leap.bitmask.bonafide.provider import Api
from pixelated.config import credentials
from pixelated.config import leap_config
-from pixelated.authentication import Authentication
from pixelated.bitmask_libraries.certs import LeapCertificate
from pixelated.bitmask_libraries.provider import LeapProvider
from pixelated.config.sessions import LeapSessionFactory
@@ -86,3 +85,15 @@ def authenticate(provider, user, password):
def init_monkeypatches():
import pixelated.extensions.requests_urllib3
+
+
+class Authentication(object):
+ def __init__(self, username, token, uuid, session_id, user_attributes):
+ self.username = username
+ self.token = token
+ self.uuid = uuid
+ self.session_id = session_id
+ self._user_attributes = user_attributes
+
+ def is_admin(self):
+ return self._user_attributes.get('is_admin', False)
diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py
index 1be07e58..f982407e 100644
--- a/service/test/support/integration/app_test_client.py
+++ b/service/test/support/integration/app_test_client.py
@@ -20,6 +20,8 @@ import shutil
import time
import uuid
import random
+
+from pixelated.config.leap import Authentication
from tempdir import TempDir
from mock import Mock
@@ -40,7 +42,6 @@ from pixelated.application import UserAgentMode, set_up_protected_resources
from pixelated.config.sessions import LeapSession
from pixelated.config.services import Services, ServicesFactory, SingleUserServicesFactory
from pixelated.config.site import PixelatedSite
-from pixelated.authentication import Authentication
from pixelated.adapter.mailstore import LeapMailStore
from pixelated.adapter.mailstore.searchable_mailstore import SearchableMailStore
diff --git a/service/test/support/integration/multi_user_client.py b/service/test/support/integration/multi_user_client.py
index 3c80bf48..0257214f 100644
--- a/service/test/support/integration/multi_user_client.py
+++ b/service/test/support/integration/multi_user_client.py
@@ -15,13 +15,13 @@
# along with Pixelated. If not, see <http://www.gnu.org/licenses/>.
from mock import patch
from mockito import mock, when, any as ANY
+from pixelated.config.leap import Authentication
from twisted.internet import defer
from pixelated.application import UserAgentMode, set_up_protected_resources
from pixelated.config.services import ServicesFactory
from pixelated.config.sessions import LeapSessionFactory
-from pixelated.authentication import Authentication
import pixelated.config.services
from pixelated.resources.root_resource import RootResource
from test.support.integration import AppTestClient
diff --git a/service/test/unit/bitmask_libraries/test_smtp_client_certificate.py b/service/test/unit/bitmask_libraries/test_smtp_client_certificate.py
index c4d0b0b7..346fd956 100644
--- a/service/test/unit/bitmask_libraries/test_smtp_client_certificate.py
+++ b/service/test/unit/bitmask_libraries/test_smtp_client_certificate.py
@@ -18,8 +18,8 @@ import unittest
import tempdir
import leap.common.certs as certs
from mockito import mock, unstub, when, any as ANY
+from pixelated.config.leap import Authentication
-from pixelated.authentication import Authentication
from pixelated.config.sessions import SmtpClientCertificate
from tempfile import NamedTemporaryFile
diff --git a/service/test/unit/test_authentication.py b/service/test/unit/test_authentication.py
index 34138b5e..f9f98af9 100644
--- a/service/test/unit/test_authentication.py
+++ b/service/test/unit/test_authentication.py
@@ -1,32 +1,58 @@
+from twisted.cred.error import UnauthorizedLogin
+from twisted.internet.defer import inlineCallbacks
from twisted.trial import unittest
+from leap.bitmask.bonafide._srp import SRPAuthError
+
+from mock import patch, Mock
+
from pixelated.authentication import Authenticator
+from pixelated.bitmask_libraries.provider import LeapProvider
+
+
+PROVIDER_JSON = {
+ "api_uri": "https://api.domain.org:4430",
+ "api_version": "1",
+ "ca_cert_fingerprint": "SHA256: some_stub_sha",
+ "ca_cert_uri": "https://domain.org/ca.crt",
+ "domain": "domain.org",
+}
class AuthenticatorTest(unittest.TestCase):
- def test_authenticates_with_username_and_password(self):
- self.fail()
+ def setUp(self):
+ with patch.object(LeapProvider, 'fetch_provider_json', return_value=PROVIDER_JSON):
+ self._leap_provider = LeapProvider('domain.org')
+
+ @inlineCallbacks
+ def test_bonafide_srp_exceptions_should_raise_unauthorized_login(self):
+ auth = Authenticator(self._leap_provider)
+ mock_bonafide_session = Mock()
+ mock_bonafide_session.authenticate = Mock(side_effect=SRPAuthError())
+ with patch('pixelated.config.leap.Session', return_value=mock_bonafide_session):
+ with self.assertRaises(UnauthorizedLogin):
+ yield auth.authenticate('username', 'password')
def test_validate_username_accepts_username(self):
- auth = Authenticator('domain.org')
+ auth = Authenticator(self._leap_provider)
self.assertTrue(auth.validate_username('username'))
def test_validate_username_accepts_email_address(self):
- auth = Authenticator('domain.org')
+ auth = Authenticator(self._leap_provider)
self.assertTrue(auth.validate_username('username@domain.org'))
def test_validate_username_denies_other_domains(self):
- auth = Authenticator('domain.org')
+ auth = Authenticator(self._leap_provider)
self.assertFalse(auth.validate_username('username@wrongdomain.org'))
def test_username_with_domain(self):
- auth = Authenticator('domain.org')
+ auth = Authenticator(self._leap_provider)
self.assertEqual('user@domain.org', auth.username_with_domain('user'))
def test_extract_username_extracts_from_plain_username(self):
- auth = Authenticator('domain.org')
+ auth = Authenticator(self._leap_provider)
self.assertEqual(auth.extract_username('user'), 'user')
def test_extract_username_extracts_from_email_address(self):
- auth = Authenticator('domain.org')
+ auth = Authenticator(self._leap_provider)
self.assertEqual(auth.extract_username('user@domain.org'), 'user')