Commit 0ba276cf by Ricardo Kirkner

allow whitelisting specific accounts (by email) to avoid the required team restriction

parents 9a5650c2 78c4e416
...@@ -114,6 +114,21 @@ in your settings.py file. ...@@ -114,6 +114,21 @@ in your settings.py file.
OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['launchpad-team-1', 'launchpad-team-2'] OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['launchpad-team-1', 'launchpad-team-2']
Some accounts can be whitelisted from this required team restriction. This is
specifically useful for doing testing. In order to whitelist an account from
the required teams restriction you can use the OPENID_EMAIL_WHITELIST_REGEXP_LIST setting.
As an example, the following value
OPENID_EMAIL_WHITELIST_REGEXP_LIST = ['foo(\+[^@]*)?@foo.com']
would whitelist users with the following emails (and other matching the regular expression)
from being in a required team:
foo@foo.com
foo+bar@foo.com
== External redirect domains == == External redirect domains ==
By default, redirecting back to an external URL after auth is forbidden. To permit redirection to external URLs on a separate domain, define ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS in your settings.py file as a list of permitted domains: By default, redirecting back to an external URL after auth is forbidden. To permit redirection to external URLs on a separate domain, define ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS in your settings.py file as a list of permitted domains:
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
__metaclass__ = type __metaclass__ = type
import re
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from openid.consumer.consumer import SUCCESS from openid.consumer.consumer import SUCCESS
...@@ -109,6 +111,11 @@ class OpenIDBackend: ...@@ -109,6 +111,11 @@ class OpenIDBackend:
matches = set(groups_required).intersection( matches = set(groups_required).intersection(
user.groups.values_list('name', flat=True)) user.groups.values_list('name', flat=True))
if not matches: if not matches:
name = 'OPENID_EMAIL_WHITELIST_REGEXP_LIST'
whitelist_regexp_list = getattr(settings, name, [])
for pattern in whitelist_regexp_list:
if re.match(pattern, user.email):
return user
return None return None
return user return user
......
...@@ -53,6 +53,8 @@ class OpenIDBackendTests(TestCase): ...@@ -53,6 +53,8 @@ class OpenIDBackendTests(TestCase):
'OPENID_LAUNCHPAD_TEAMS_REQUIRED', []) 'OPENID_LAUNCHPAD_TEAMS_REQUIRED', [])
self.old_openid_launchpad_teams_mapping_auto = getattr(settings, self.old_openid_launchpad_teams_mapping_auto = getattr(settings,
'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False) 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
self.old_openid_email_whitelist_regexp_list = getattr(settings,
'OPENID_EMAIL_WHITELIST_REGEXP_LIST', [])
def tearDown(self): def tearDown(self):
settings.OPENID_USE_EMAIL_FOR_USERNAME = \ settings.OPENID_USE_EMAIL_FOR_USERNAME = \
...@@ -61,6 +63,8 @@ class OpenIDBackendTests(TestCase): ...@@ -61,6 +63,8 @@ class OpenIDBackendTests(TestCase):
self.old_openid_launchpad_teams_required) self.old_openid_launchpad_teams_required)
settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = ( settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = (
self.old_openid_launchpad_teams_mapping_auto) self.old_openid_launchpad_teams_mapping_auto)
settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = (
self.old_openid_email_whitelist_regexp_list)
def test_extract_user_details_sreg(self): def test_extract_user_details_sreg(self):
expected = { expected = {
...@@ -272,6 +276,58 @@ class OpenIDBackendTests(TestCase): ...@@ -272,6 +276,58 @@ class OpenIDBackendTests(TestCase):
self.assertIsNotNone(user) self.assertIsNotNone(user)
def test_authenticate_when_not_in_required_team_but_email_whitelisted(self):
settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = [
'foo(\+[^@]*)?@foo.com',
]
assert Group.objects.filter(name='team').count() == 0
response = self.make_openid_response(
sreg_args=dict(nickname='someuser', email='foo@foo.com'),
teams_args=dict(is_member='foo'))
user = self.backend.authenticate(openid_response=response)
self.assertIsNotNone(user)
response = self.make_openid_response(
sreg_args=dict(nickname='someuser', email='foo+bar@foo.com'),
teams_args=dict(is_member='foo'))
user = self.backend.authenticate(openid_response=response)
self.assertIsNotNone(user)
def test_authenticate_whitelisted_email_multiple_patterns(self):
settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = [
'foo@foo.com', 'bar@foo.com',
]
assert Group.objects.filter(name='team').count() == 0
response = self.make_openid_response(
sreg_args=dict(nickname='someuser', email='bar@foo.com'),
teams_args=dict(is_member='foo'))
user = self.backend.authenticate(openid_response=response)
self.assertIsNotNone(user)
def test_authenticate_whitelisted_email_not_match(self):
settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = [
'foo@foo.com',
]
assert Group.objects.filter(name='team').count() == 0
response = self.make_openid_response(
sreg_args=dict(nickname='someuser', email='bar@foo.com'),
teams_args=dict(is_member='foo'))
user = self.backend.authenticate(openid_response=response)
self.assertIsNone(user)
def suite(): def suite():
return unittest.TestLoader().loadTestsFromName(__name__) return unittest.TestLoader().loadTestsFromName(__name__)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment