Skip to content

enterprise/requests: Add ability to request access#24183

Open
BeryJu wants to merge 30 commits into
mainfrom
pam-v3
Open

enterprise/requests: Add ability to request access#24183
BeryJu wants to merge 30 commits into
mainfrom
pam-v3

Conversation

@BeryJu

@BeryJu BeryJu commented Jul 19, 2026

Copy link
Copy Markdown
Member

replaces #23618

BeryJu added 20 commits July 16, 2026 12:32
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>

# Conflicts:
#	authentik/policies/engine.py
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
@BeryJu
BeryJu requested review from a team as code owners July 19, 2026 17:11
@netlify

netlify Bot commented Jul 19, 2026

Copy link
Copy Markdown

Deploy Preview for authentik-integrations ready!

Name Link
🔨 Latest commit 5efd127
🔍 Latest deploy log https://app.netlify.com/projects/authentik-integrations/deploys/6a5e2b6944f4bc000791c102
😎 Deploy Preview https://deploy-preview-24183--authentik-integrations.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 project configuration.

@netlify

netlify Bot commented Jul 19, 2026

Copy link
Copy Markdown

Deploy Preview for authentik-storybook ready!

Name Link
🔨 Latest commit 5efd127
🔍 Latest deploy log https://app.netlify.com/projects/authentik-storybook/deploys/6a5e2b696ed7c50008e9cf8d
😎 Deploy Preview https://deploy-preview-24183--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 project configuration.

@netlify

netlify Bot commented Jul 19, 2026

Copy link
Copy Markdown

Deploy Preview for authentik-docs ready!

Name Link
🔨 Latest commit 5efd127
🔍 Latest deploy log https://app.netlify.com/projects/authentik-docs/deploys/6a5e2b69690c5d00095046da
😎 Deploy Preview https://deploy-preview-24183--authentik-docs.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 project configuration.

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
3888 1 3887 1
View the top 1 failed test(s) by shortest run time
authentik.root.tests.test_many_to_many.TestManyToMany::test_all_many_to_many_relations_are_explicit
Stack Traces | 0.021s run time
self = <unittest.case._Outcome object at 0x7fd9b3c1f7e0>
test_case = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>
subTest = False

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

.../hostedtoolcache/Python/3.14.6...................../x64/lib/python3.14/unittest/case.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>
result = <TestCaseFunction test_all_many_to_many_relations_are_explicit>

    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.14.6...................../x64/lib/python3.14/unittest/case.py:669: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>
method = <bound method TestManyToMany.test_all_many_to_many_relations_are_explicit of <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>>

    def _callTestMethod(self, method):
>       result = method()
                 ^^^^^^^^

.../hostedtoolcache/Python/3.14.6...................../x64/lib/python3.14/unittest/case.py:615: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>

    def test_all_many_to_many_relations_are_explicit(self):
        implicit_m2ms = []
        exceptions = [DjangoGroup]
    
        for model in apps.get_models():
            if model in exceptions:
                continue
            for field in model._meta.get_fields():
                if not isinstance(field, ManyToManyField):
                    continue
                if field.remote_field.through._meta.auto_created:
                    implicit_m2ms.append(f"{model.__name__}.{field.name}")
    
>       self.assertEqual(implicit_m2ms, [])

.../root/tests/test_many_to_many.py:21: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>
first = ['RequestRule.notification_transports'], second = [], msg = None

    def assertEqual(self, first, second, msg=None):
        """Fail if the two objects are unequal as determined by the '=='
           operator.
        """
        assertion_func = self._getAssertEqualityFunc(first, second)
>       assertion_func(first, second, msg=msg)

.../hostedtoolcache/Python/3.14.6...................../x64/lib/python3.14/unittest/case.py:925: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>
list1 = ['RequestRule.notification_transports'], list2 = [], msg = None

    def assertListEqual(self, list1, list2, msg=None):
        """A list-specific equality assertion.
    
        Args:
            list1: The first list to compare.
            list2: The second list to compare.
            msg: Optional message to use on failure instead of a list of
                    differences.
    
        """
>       self.assertSequenceEqual(list1, list2, msg, seq_type=list)

.../hostedtoolcache/Python/3.14.6...................../x64/lib/python3.14/unittest/case.py:1131: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>
seq1 = ['RequestRule.notification_transports'], seq2 = []
msg = "Lists differ: ['RequestRule.notification_transports'] != []\n\nFirst list contains 1 additional elements.\nFirst extra element 0:\n'RequestRule.notification_transports'\n\n- ['RequestRule.notification_transports']\n+ []"
seq_type = <class 'list'>

    def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None):
        """An equality assertion for ordered sequences (like lists and tuples).
    
        For the purposes of this function, a valid ordered sequence type is one
        which can be indexed, has a length, and has an equality operator.
    
        Args:
            seq1: The first sequence to compare.
            seq2: The second sequence to compare.
            seq_type: The expected datatype of the sequences, or None if no
                    datatype should be enforced.
            msg: Optional message to use on failure instead of a list of
                    differences.
        """
        if seq_type is not None:
            seq_type_name = seq_type.__name__
            if not isinstance(seq1, seq_type):
                raise self.failureException('First sequence is not a %s: %s'
                                        % (seq_type_name, safe_repr(seq1)))
            if not isinstance(seq2, seq_type):
                raise self.failureException('Second sequence is not a %s: %s'
                                        % (seq_type_name, safe_repr(seq2)))
        else:
            seq_type_name = "sequence"
    
        differing = None
        try:
            len1 = len(seq1)
        except (TypeError, NotImplementedError):
            differing = 'First %s has no length.    Non-sequence?' % (
                    seq_type_name)
    
        if differing is None:
            try:
                len2 = len(seq2)
            except (TypeError, NotImplementedError):
                differing = 'Second %s has no length.    Non-sequence?' % (
                        seq_type_name)
    
        if differing is None:
            if seq1 == seq2:
                return
    
            differing = '%ss differ: %s != %s\n' % (
                    (seq_type_name.capitalize(),) +
                    _common_shorten_repr(seq1, seq2))
    
            for i in range(min(len1, len2)):
                try:
                    item1 = seq1[i]
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('\nUnable to index element %d of first %s\n' %
                                 (i, seq_type_name))
                    break
    
                try:
                    item2 = seq2[i]
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('\nUnable to index element %d of second %s\n' %
                                 (i, seq_type_name))
                    break
    
                if item1 != item2:
                    differing += ('\nFirst differing element %d:\n%s\n%s\n' %
                                 ((i,) + _common_shorten_repr(item1, item2)))
                    break
            else:
                if (len1 == len2 and seq_type is None and
                    type(seq1) != type(seq2)):
                    # The sequences are the same, but have differing types.
                    return
    
            if len1 > len2:
                differing += ('\nFirst %s contains %d additional '
                             'elements.\n' % (seq_type_name, len1 - len2))
                try:
                    differing += ('First extra element %d:\n%s\n' %
                                  (len2, safe_repr(seq1[len2])))
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('Unable to index element %d '
                                  'of first %s\n' % (len2, seq_type_name))
            elif len1 < len2:
                differing += ('\nSecond %s contains %d additional '
                             'elements.\n' % (seq_type_name, len2 - len1))
                try:
                    differing += ('First extra element %d:\n%s\n' %
                                  (len1, safe_repr(seq2[len1])))
                except (TypeError, IndexError, NotImplementedError):
                    differing += ('Unable to index element %d '
                                  'of second %s\n' % (len1, seq_type_name))
        standardMsg = differing
        diffMsg = '\n' + '\n'.join(
            difflib.ndiff(pprint.pformat(seq1).splitlines(),
                          pprint.pformat(seq2).splitlines()))
    
        standardMsg = self._truncateMessage(standardMsg, diffMsg)
        msg = self._formatMessage(msg, standardMsg)
>       self.fail(msg)

.../hostedtoolcache/Python/3.14.6...................../x64/lib/python3.14/unittest/case.py:1113: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.root.tests.test_many_to_many.TestManyToMany testMethod=test_all_many_to_many_relations_are_explicit>
msg = "Lists differ: ['RequestRule.notification_transports'] != []\n\nFirst list contains 1 additional elements.\nFirst extra element 0:\n'RequestRule.notification_transports'\n\n- ['RequestRule.notification_transports']\n+ []"

    def fail(self, msg=None):
        """Fail immediately, with the given message."""
>       raise self.failureException(msg)
E       AssertionError: Lists differ: ['RequestRule.notification_transports'] != []
E       
E       First list contains 1 additional elements.
E       First extra element 0:
E       'RequestRule.notification_transports'
E       
E       - ['RequestRule.notification_transports']
E       + []

.../hostedtoolcache/Python/3.14.6...................../x64/lib/python3.14/unittest/case.py:750: 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 added 2 commits July 19, 2026 18:42
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
@BeryJu
BeryJu requested a review from a team as a code owner July 19, 2026 18:02
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
BeryJu added 7 commits July 19, 2026 20:39
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
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