From 7e805dff08d4cbe14abab567edb7a301bdde6dda Mon Sep 17 00:00:00 2001 From: Bruno Wagner Date: Thu, 20 Oct 2016 19:13:00 -0200 Subject: Moving authentication out of login_resource This is ongoing work to be able to accept and validate user domain on login (so the user can use or ) We are extracting the authentication logic from login_resource to be able to test and cover the cases we need --- service/pixelated/authentication.py | 32 ++++++++++++++++++++ service/pixelated/config/authentication.py | 11 ------- service/pixelated/config/leap.py | 2 +- .../test/support/integration/app_test_client.py | 2 +- .../test/support/integration/multi_user_client.py | 2 +- .../test_smtp_client_certificate.py | 2 +- service/test/unit/test_authentication.py | 34 ++++++++++++++++++++++ 7 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 service/pixelated/authentication.py delete mode 100644 service/pixelated/config/authentication.py create mode 100644 service/test/unit/test_authentication.py (limited to 'service') diff --git a/service/pixelated/authentication.py b/service/pixelated/authentication.py new file mode 100644 index 00000000..4b268435 --- /dev/null +++ b/service/pixelated/authentication.py @@ -0,0 +1,32 @@ +import re +from email.utils import parseaddr + +class Authentication(object): + + def __init__(self, domain): + self.domain = domain + # self.token = token + # self.uuid = uuid + # self.session_id = session_id + # self._user_attributes = user_attributes + + def authenticate(self, username, password): + self.username = self.validate_username(username) + self.srp_auth(username, password) + + def validate_username(self, username): + if '@' not in username: return True + extracted_username = self.extract_username(username) + if self.username_with_domain(extracted_username) == username: + return True + else: + return False + + def extract_username(self, username): + return re.search('^([^@]+)@?.*$', username).group(1) + + def username_with_domain(self, username): + return '%s@%s' % (username, self.domain) + + def is_admin(self): + return self._user_attributes.get('is_admin', False) diff --git a/service/pixelated/config/authentication.py b/service/pixelated/config/authentication.py deleted file mode 100644 index dc8439cc..00000000 --- a/service/pixelated/config/authentication.py +++ /dev/null @@ -1,11 +0,0 @@ -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/pixelated/config/leap.py b/service/pixelated/config/leap.py index b060170f..5dbfe21b 100644 --- a/service/pixelated/config/leap.py +++ b/service/pixelated/config/leap.py @@ -13,7 +13,7 @@ from leap.bitmask.bonafide.provider import Api from pixelated.config import credentials from pixelated.config import leap_config -from pixelated.config.authentication import Authentication +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 diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py index 4e7b8c66..1be07e58 100644 --- a/service/test/support/integration/app_test_client.py +++ b/service/test/support/integration/app_test_client.py @@ -40,7 +40,7 @@ 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.config.authentication import Authentication +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 420ff54b..3c80bf48 100644 --- a/service/test/support/integration/multi_user_client.py +++ b/service/test/support/integration/multi_user_client.py @@ -21,7 +21,7 @@ from pixelated.application import UserAgentMode, set_up_protected_resources from pixelated.config.services import ServicesFactory from pixelated.config.sessions import LeapSessionFactory -from pixelated.config.authentication import Authentication +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 c9a51694..c4d0b0b7 100644 --- a/service/test/unit/bitmask_libraries/test_smtp_client_certificate.py +++ b/service/test/unit/bitmask_libraries/test_smtp_client_certificate.py @@ -19,7 +19,7 @@ import tempdir import leap.common.certs as certs from mockito import mock, unstub, when, any as ANY -from pixelated.config.authentication 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 new file mode 100644 index 00000000..2fb97d69 --- /dev/null +++ b/service/test/unit/test_authentication.py @@ -0,0 +1,34 @@ +from twisted.trial import unittest + +from leap.bitmask.bonafide._srp import SRPAuthError +from pixelated.authentication import Authentication + + +class AuthenticationTest(unittest.TestCase): + + def test_authenticates_with_username_and_password(self): + self.fail() + + def test_validate_username_accepts_username(self): + auth = Authentication('domain.org') + self.assertTrue(auth.validate_username('username')) + + def test_validate_username_accepts_email_address(self): + auth = Authentication('domain.org') + self.assertTrue(auth.validate_username('username@domain.org')) + + def test_validate_username_denies_other_domains(self): + auth = Authentication('domain.org') + self.assertFalse(auth.validate_username('username@wrongdomain.org')) + + def test_username_with_domain(self): + auth = Authentication('domain.org') + self.assertEqual('user@domain.org', auth.username_with_domain('user')) + + def test_extract_username_extracts_from_plain_username(self): + auth = Authentication('domain.org') + self.assertEqual(auth.extract_username('user'), 'user') + + def test_extract_username_extracts_from_email_address(self): + auth = Authentication('domain.org') + self.assertEqual(auth.extract_username('user@domain.org'), 'user') -- cgit v1.2.3