Skip to content

Commit

Permalink
[CI] Drop pyfakefs, use custom auth fixture
Browse files Browse the repository at this point in the history
- Introduces a custom auth fixture with a few broken "plugins" and a
  "working" plugin to test.
- Tests that the broken ones fail properly and that the working one
  can be used to auth.

Signed-off-by: Rick Elrod <[email protected]>
  • Loading branch information
relrod committed Nov 25, 2023
1 parent 153c5d9 commit 2737d53
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 16 deletions.
18 changes: 18 additions & 0 deletions ansible_base/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,24 @@ def local_authenticator(db):
authenticator.delete()


@pytest.fixture
def custom_authenticator(db):
from ansible_base.models import Authenticator

authenticator = Authenticator.objects.create(
name="Test Custom Authenticator",
enabled=True,
create_objects=True,
users_unique=False,
remove_users=True,
type="ansible_base.tests.fixtures.authenticator_plugins.custom",
configuration={},
)
yield authenticator
authenticator.authenticator_user.all().delete()
authenticator.delete()


@pytest.fixture
def keycloak_authenticator(db):
from ansible_base.models import Authenticator
Expand Down
Empty file.
Empty file.
3 changes: 3 additions & 0 deletions ansible_base/tests/fixtures/authenticator_plugins/broken.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import sys # noqa: F401

from nothing import this_does_not_exist # noqa: F401
23 changes: 23 additions & 0 deletions ansible_base/tests/fixtures/authenticator_plugins/custom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import logging

from django.contrib.auth import get_user_model

from ansible_base.authenticator_plugins.base import AbstractAuthenticatorPlugin

logger = logging.getLogger('ansible_base.tests.fixtures.authenticator_plugins')


class AuthenticatorPlugin(AbstractAuthenticatorPlugin):
def __init__(self, database_instance=None, *args, **kwargs):
super().__init__(database_instance, *args, **kwargs)
self.configuration_encrypted_fields = []
self.type = "custom"
self.set_logger(logger)
self.category = "password"

def authenticate(self, request, username=None, password=None, **kwargs):
if username == "admin" and password == "hello123":
user = get_user_model().objects.get(username=username)
return user

return None
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import sys # noqa: F401

from nothing import this_does_not_exist # noqa: F401
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import sys

from django.urls import reverse
from pyfakefs.fake_filesystem_unittest import Patcher


def test_plugin_authenticator_view(admin_api_client):
Expand All @@ -19,20 +16,19 @@ def test_plugin_authenticator_view(admin_api_client):
assert 'ansible_base.authenticator_plugins.local' in auth_types


def test_plugin_authenticator_view_import_error(admin_api_client, shut_up_logging):
def test_plugin_authenticator_view_import_error(admin_api_client, shut_up_logging, settings):
"""
Test that import errors are returned as expected.
"""

# We use pyfakefs here, copy in the real directory, and then create a fake broken file.
# We *avoid* the 'fs' fixture because it *breaks DRF in weird ways*.
url = reverse("authenticator_plugin-view")
fixture_module = "ansible_base.tests.fixtures.authenticator_plugins"
settings.ANSIBLE_BASE_AUTHENTICATOR_CLASS_PREFIXES = [
"ansible_base.authenticator_plugins",
fixture_module,
]

with Patcher() as patcher:
patcher.fs.add_real_directory(sys.modules['ansible_base.authenticator_plugins'].__path__[0])
patcher.fs.create_file(sys.modules['ansible_base.authenticator_plugins'].__path__[0] + '/broken.py', contents='invalid')
patcher.fs.create_file(sys.modules['ansible_base.authenticator_plugins'].__path__[0] + '/really_broken.py', contents='invalid')
response = admin_api_client.get(url)
url = reverse("authenticator_plugin-view")
response = admin_api_client.get(url)

assert response.status_code == 200
assert 'authenticators' in response.data
Expand All @@ -43,5 +39,29 @@ def test_plugin_authenticator_view_import_error(admin_api_client, shut_up_loggin
assert 'broken' not in auth_types

assert 'errors' in response.data
assert 'The specified authenticator type ansible_base.authenticator_plugins.broken could not be loaded' in response.data['errors']
assert 'The specified authenticator type ansible_base.authenticator_plugins.really_broken could not be loaded' in response.data['errors']
assert f'The specified authenticator type {fixture_module}.broken could not be loaded' in response.data['errors']
assert f'The specified authenticator type {fixture_module}.really_broken could not be loaded' in response.data['errors']


def test_plugin_authenticator_plugin_from_custom_module(admin_user, unauthenticated_api_client, shut_up_logging, settings, custom_authenticator):
"""
Test that we can auth with a fully custom authenticator plugin.
"""

fixture_module = "ansible_base.tests.fixtures.authenticator_plugins"
settings.ANSIBLE_BASE_AUTHENTICATOR_CLASS_PREFIXES = [
"ansible_base.authenticator_plugins",
fixture_module,
]

url = reverse("authenticator-detail", kwargs={'pk': custom_authenticator.pk})

client = unauthenticated_api_client
client.login(username=admin_user.username, password="wrongpw")
response = client.get(url)
assert response.status_code == 403

client.login(username=admin_user.username, password="hello123")
response = client.get(url)
assert response.status_code == 200
assert response.data['type'] == f'{fixture_module}.custom'
2 changes: 1 addition & 1 deletion ansible_base/views/authenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class AuthenticatorViewSet(ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
API endpoint that allows authenticators to be viewed or edited.
"""

queryset = Authenticator.objects.all()
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ legacy_tox_ini = """
deps =
-r{toxinidir}/requirements/requirements.txt
-r{toxinidir}/requirements/requirements_dev.txt
pyfakefs
commands = pytest -n auto --cov=. --cov-report=xml:coverage.xml --cov-report=html --cov-report=json --cov-branch {env:GATEWAY_TEST_DIRS:ansible_base/tests} {posargs}
[testenv:check]
Expand Down

0 comments on commit 2737d53

Please sign in to comment.