Implement tacacs+ auth backend.

This commit is contained in:
Aaron Tan
2017-03-23 16:20:03 -04:00
parent f2c99eeaf5
commit fd4aaa6ca9
8 changed files with 200 additions and 13 deletions

38
awx/sso/tests/conftest.py Normal file
View File

@@ -0,0 +1,38 @@
import pytest
from django.contrib.auth.models import User
from awx.sso.backends import TACACSPlusBackend
@pytest.fixture
def tacacsplus_backend():
return TACACSPlusBackend()
@pytest.fixture
def existing_tacacsplus_user():
try:
user = User.objects.get(username="foo")
except User.DoesNotExist:
user = User(username="foo")
user.save()
return user
@pytest.fixture
def feature_enabled():
def func(feature):
def inner(name):
return name == feature
return inner
return func
@pytest.fixture
def feature_disabled():
def func(feature):
def inner(name):
return False
return inner
return func

View File

@@ -0,0 +1,24 @@
import pytest
import mock
@pytest.mark.django_db
def test_fetch_user_if_exist(tacacsplus_backend, existing_tacacsplus_user):
new_user = tacacsplus_backend._get_or_set_user("foo", "password")
assert new_user == existing_tacacsplus_user
@pytest.mark.django_db
def test_create_user_if_not_exist(tacacsplus_backend, existing_tacacsplus_user):
with mock.patch('awx.sso.backends.logger') as mocked_logger:
new_user = tacacsplus_backend._get_or_set_user("bar", "password")
mocked_logger.debug.assert_called_once_with(
'Created TACACS+ user bar'
)
assert new_user != existing_tacacsplus_user
@pytest.mark.django_db
def test_created_user_has_no_usable_password(tacacsplus_backend):
new_user = tacacsplus_backend._get_or_set_user("bar", "password")
assert not new_user.has_usable_password()

View File

@@ -0,0 +1,65 @@
import mock
def test_empty_host_fails_auth(tacacsplus_backend):
with mock.patch('awx.sso.backends.django_settings') as settings:
settings.TACACSPLUS_HOST = ''
ret_user = tacacsplus_backend.authenticate(u"user", u"pass")
assert ret_user is None
def test_disabled_enterprise_auth_fails_auth(tacacsplus_backend, feature_disabled):
with mock.patch('awx.sso.backends.django_settings') as settings,\
mock.patch('awx.sso.backends.logger') as logger,\
mock.patch('awx.sso.backends.feature_enabled', feature_disabled('enterprise_auth')):
settings.TACACSPLUS_HOST = 'localhost'
ret_user = tacacsplus_backend.authenticate(u"user", u"pass")
assert ret_user is None
logger.error.assert_called_once_with(
"Unable to authenticate, license does not support TACACS+ authentication"
)
def test_client_raises_exception(tacacsplus_backend, feature_enabled):
client = mock.MagicMock()
client.authenticate.side_effect=Exception("foo")
with mock.patch('awx.sso.backends.django_settings') as settings,\
mock.patch('awx.sso.backends.logger') as logger,\
mock.patch('awx.sso.backends.feature_enabled', feature_enabled('enterprise_auth')),\
mock.patch('tacacs_plus.TACACSClient', return_value=client):
settings.TACACSPLUS_HOST = 'localhost'
settings.TACACSPLUS_AUTH_PROTOCOL = 'ascii'
ret_user = tacacsplus_backend.authenticate(u"user", u"pass")
assert ret_user is None
logger.exception.assert_called_once_with(
"TACACS+ Authentication Error: foo"
)
def test_client_return_invalid_fails_auth(tacacsplus_backend, feature_enabled):
auth = mock.MagicMock()
auth.valid = False
client = mock.MagicMock()
client.authenticate.return_value = auth
with mock.patch('awx.sso.backends.django_settings') as settings,\
mock.patch('awx.sso.backends.feature_enabled', feature_enabled('enterprise_auth')),\
mock.patch('tacacs_plus.TACACSClient', return_value=client):
settings.TACACSPLUS_HOST = 'localhost'
settings.TACACSPLUS_AUTH_PROTOCOL = 'ascii'
ret_user = tacacsplus_backend.authenticate(u"user", u"pass")
assert ret_user is None
def test_client_return_valid_passes_auth(tacacsplus_backend, feature_enabled):
auth = mock.MagicMock()
auth.valid = True
client = mock.MagicMock()
client.authenticate.return_value = auth
with mock.patch('awx.sso.backends.django_settings') as settings,\
mock.patch('awx.sso.backends.feature_enabled', feature_enabled('enterprise_auth')),\
mock.patch('tacacs_plus.TACACSClient', return_value=client),\
mock.patch.object(tacacsplus_backend, '_get_or_set_user', return_value="user"):
settings.TACACSPLUS_HOST = 'localhost'
settings.TACACSPLUS_AUTH_PROTOCOL = 'ascii'
ret_user = tacacsplus_backend.authenticate(u"user", u"pass")
assert ret_user == "user"