Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib/sync/outgoing: add dry run #13244

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open

lib/sync/outgoing: add dry run #13244

wants to merge 9 commits into from

Conversation

BeryJu
Copy link
Member

@BeryJu BeryJu commented Feb 25, 2025

Details

Add the option for dry-run syncs for SCIM and Google Workspace, to make implementation easier and not needing to worry that incorrect settings might delete users


Checklist

  • Local tests pass (ak test authentik/)
  • The code has been formatted (make lint-fix)

If an API change has been made

  • The API schema has been updated (make gen-build)

If changes to the frontend have been made

  • The code has been formatted (make web)

If applicable

  • The documentation has been updated
  • The documentation has been formatted (make website)

@BeryJu BeryJu requested a review from a team as a code owner February 25, 2025 08:23
Copy link

netlify bot commented Feb 25, 2025

Deploy Preview for authentik-docs canceled.

Name Link
🔨 Latest commit 2a1b9a7
🔍 Latest deploy log https://app.netlify.com/sites/authentik-docs/deploys/67c0560874a67500087b248d

Copy link

netlify bot commented Feb 25, 2025

Deploy Preview for authentik-storybook ready!

Name Link
🔨 Latest commit 2a1b9a7
🔍 Latest deploy log https://app.netlify.com/sites/authentik-storybook/deploys/67c0560888356e00087e7dc4
😎 Deploy Preview https://deploy-preview-13244--authentik-storybook.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

codecov bot commented Feb 25, 2025

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1718 1 1717 2
View the full list of 1 ❄️ flaky tests
authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage::test_session_management

Flake rate in main: 10.97% (Passed 211 times, Failed 26 times)

Stack Traces | 0.977s run time
self = <unittest.case._Outcome object at 0x7f954ad01670>
test_case = <authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage testMethod=test_session_management>
subTest = False

    @contextlib.contextmanager
    def testPartExecutor(self, test_case, subTest=False):
        old_success = self.success
        self.success = True
        try:
>           yield

.../hostedtoolcache/Python/3.12.9.............../x64/lib/python3.12/unittest/case.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage testMethod=test_session_management>
result = <TestCaseFunction test_session_management>

    def run(self, result=None):
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            stopTestRun = getattr(result, 'stopTestRun', None)
            if startTestRun is not None:
                startTestRun()
        else:
            stopTestRun = None
    
        result.startTest(self)
        try:
            testMethod = getattr(self, self._testMethodName)
            if (getattr(self.__class__, "__unittest_skip__", False) or
                getattr(testMethod, "__unittest_skip__", False)):
                # If the class or method was skipped.
                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                            or getattr(testMethod, '__unittest_skip_why__', ''))
                _addSkip(result, self, skip_why)
                return result
    
            expecting_failure = (
                getattr(self, "__unittest_expecting_failure__", False) or
                getattr(testMethod, "__unittest_expecting_failure__", False)
            )
            outcome = _Outcome(result)
            start_time = time.perf_counter()
            try:
                self._outcome = outcome
    
                with outcome.testPartExecutor(self):
                    self._callSetUp()
                if outcome.success:
                    outcome.expecting_failure = expecting_failure
                    with outcome.testPartExecutor(self):
>                       self._callTestMethod(testMethod)

.../hostedtoolcache/Python/3.12.9.............../x64/lib/python3.12/unittest/case.py:634: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage testMethod=test_session_management>
method = <bound method TestAuthenticatorEmailStage.test_session_management of <authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage testMethod=test_session_management>>

    def _callTestMethod(self, method):
>       if method() is not None:

.../hostedtoolcache/Python/3.12.9.............../x64/lib/python3.12/unittest/case.py:589: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage testMethod=test_session_management>

    def test_session_management(self):
        """Test session device management"""
        # Test device creation in session
        with patch(
            "authentik.stages.authenticator_email.models.AuthenticatorEmailStage.backend_class",
            PropertyMock(return_value=EmailBackend),
        ):
            # Delete any existing devices for this test
            EmailDevice.objects.filter(user=self.user).delete()
    
            response = self.client.get(
                reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
            )
            self.assertIn(SESSION_KEY_EMAIL_DEVICE, self.client.session)
            device = self.client.session[SESSION_KEY_EMAIL_DEVICE]
            self.assertIsInstance(device, EmailDevice)
            self.assertFalse(device.confirmed)
            self.assertEqual(device.user, self.user)
    
            # Test device confirmation and cleanup
            device.confirmed = True
            device.email = "[email protected]"  # Use a different email
            self.client.session[SESSION_KEY_EMAIL_DEVICE] = device
            self.client.session.save()
            response = self.client.post(
                reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
                data={"component": "ak-stage-authenticator-email", "code": device.token},
            )
            self.assertEqual(response.status_code, 200)
            self.assertTrue(device.confirmed)
            # Get a fresh session to check if the key was removed
            session = self.client.session
            session.save()
            session.load()
>           self.assertNotIn(SESSION_KEY_EMAIL_DEVICE, session)

.../stages/authenticator_email/tests.py:307: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage testMethod=test_session_management>
member = '.../stages/authenticator_email/email_device'
container = <django.contrib.sessions.backends.cache.SessionStore object at 0x7f9543f9dbe0>
msg = None

    def assertNotIn(self, member, container, msg=None):
        """Just like self.assertTrue(a not in b), but with a nicer default message."""
        if member in container:
            standardMsg = '%s unexpectedly found in %s' % (safe_repr(member),
                                                        safe_repr(container))
>           self.fail(self._formatMessage(msg, standardMsg))

.../hostedtoolcache/Python/3.12.9.............../x64/lib/python3.12/unittest/case.py:1159: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.stages.authenticator_email.tests.TestAuthenticatorEmailStage testMethod=test_session_management>
msg = "'.../stages/authenticator_email/email_device' unexpectedly found in <django.contrib.sessions.backends.cache.SessionStore object at 0x7f9543f9dbe0>"

    def fail(self, msg=None):
        """Fail immediately, with the given message."""
>       raise self.failureException(msg)
E       AssertionError: '.../stages/authenticator_email/email_device' unexpectedly found in <django.contrib.sessions.backends.cache.SessionStore object at 0x7f9543f9dbe0>

.../hostedtoolcache/Python/3.12.9.............../x64/lib/python3.12/unittest/case.py:715: AssertionError

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@BeryJu BeryJu requested review from a team as code owners February 25, 2025 13:11
Copy link
Contributor

github-actions bot commented Feb 25, 2025

authentik PR Installation instructions

Instructions for docker-compose

Add the following block to your .env file:

AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=gh-2a1b9a750a7103c5400dea762cc67ecfb4f435cf
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s

Afterwards, run the upgrade commands from the latest release notes.

Instructions for Kubernetes

Add the following block to your values.yml file:

authentik:
    outposts:
        container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
global:
    image:
        repository: ghcr.io/goauthentik/dev-server
        tag: gh-2a1b9a750a7103c5400dea762cc67ecfb4f435cf

Afterwards, run the upgrade commands from the latest release notes.

@BeryJu BeryJu force-pushed the lib/sync/outgoing/dry-run branch from 3ae43e1 to fb45159 Compare February 27, 2025 10:57
Signed-off-by: Jens Langhammer <[email protected]>
Signed-off-by: Jens Langhammer <[email protected]>
Signed-off-by: Jens Langhammer <[email protected]>
Signed-off-by: Jens Langhammer <[email protected]>
Signed-off-by: Jens Langhammer <[email protected]>
Signed-off-by: Jens Langhammer <[email protected]>
Signed-off-by: Jens Langhammer <[email protected]>
@BeryJu BeryJu force-pushed the lib/sync/outgoing/dry-run branch from fb45159 to cd6ef98 Compare February 27, 2025 11:36
Signed-off-by: Jens Langhammer <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant