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

web/admin: add application bindings to the application wizard #11462

Open
wants to merge 68 commits into
base: web/update-provider-forms-for-invalidation
Choose a base branch
from

Conversation

kensternberg-authentik
Copy link
Contributor

@kensternberg-authentik kensternberg-authentik commented Sep 20, 2024

web: wizard for applications, now with bindings!

What

Purpose

  • Add policy bindings to the application wizard

The Wizard Base:

  • Restructures the Wizard base code.
    • ak-wizard-steps holds the steps and listens for NavigationRequest events to move from one step to the next.
    • WizardStep is a base class (no component registration provided) that provides the whole frame, not just the form. It receives the navigation content for the sidebar from ak-wizard-steps, and provides the styling for the header, footer, sidebar, and main form. It has abstractions for buttons, renderMain(), handleButton(), handleEnable(), in a section well-marked as “Public API”. Steps inherit from this class.

Conceptually:

  • A wizard is a series of pages (“steps”) with a distinct beginning and end, linked in a series, to complete a task.
  • Later steps in the series are inaccessible until an earlier steps has granted access to it.
  • Access is predicated on the earlier step being complete and valid. The developer is responsible for determining what “complete and valid” means.
  • The series is visible, giving the customer a sense of how much effort is needed to complete the task.
  • A parent object maintains (and can modify as needed) the list of steps. It can maintain the information being collected from the user. Alternatively, that information can be kept in each step.

Details:

  • Keeping with the Lit paradigm, “requests to change the system flow up, information changed by valid requests flows down.”
  • The information flows up using events: WizardNavigation, WizardUpdate, WizardClose.
  • The information flows down using properties.

The Application Wizard

  • ak-application-wizard-main holds the list of steps, providing a unique slot name for each.
    • It maintains the ApplicationWizardState object.
  • ApplicationWizardStep inherits from WizardStep and provides:
    • A means of extraction information from forms
    • A convenience method for updating the ApplicationWizardState object, enabling future steps, and navigating to a future step, in the correct order.
    • A method for cleaning error from the error reporting mechanism as the user navigates from an error-handling state.
    • The title, description, and cancelability of the wizard.
  • Steps:
    • step: Handles the application. A good starting point for understanding the point of the Wizard. Check the handleButton() method to understand how we enable or disable access to future steps.
    • provider-choice: Just a list. Shows validation without the form.
    • provider: Uses a very esoteric Lit feature, unsafeStaticTag, which enables the display to show anything that conforms to the expectations of ApplicationWizardProviderForm.
      • ApplicationWizardProviderForm repeats some of the base of ApplicationWizardStep, but allows us to provide multiple variants on a single form without having to create separate steps for each form.
      • The forms (provider-for-ldap, provider-for-radius) are therefore just the form and any fetchers needed to populate it.
    • bindings: Shows the table of bindings. Has a custom display for “This table is empty.”
    • edit-binding: Showcase for the SearchSelectEZ configuration format. Has an override on the handleButton feature to figure out which binding is about to be overridden. Is also a .hidden page; it doesn’t show up on the navigation sidebar, as is only navigable-to by buttons not associated with the button bar at the bottom.
    • submit: Has a lot of machinery of state: Reviewing with errors, reviewing without errors, running submission, and success. Uses ts-pattern a lot to make sure the state/request pairs make sense.

Why !?!?!?

The key insight is that, even though a wizard is a series in order, that order can’t be simply maintained in a list. The parent needs various strategies for swapping pages in and out of the sequence, while still maintaining a coherent idea of “flow” and providing the visual cues the user needs to feel confident that the work can be completed and completed quickly. The entire mechanism for using an array and index to navigate, with index numbering, blocked the implementation of the bindings pages.

One thing led to another. Sigh Really wish this hadn’t been as much of a mess as it turned out. The end result is pretty good, though. Definitely re-usable.

One important feature to note is that the wizard is not tied to the ModalButton object; it’s simply embedded in a modal as-needed. This allows us to use wizards in other places, such as just being in a DIV, or just a page on its own.

Checklist

  • The code has been formatted (make web)

…from the backend

Provide an alternative, readonly, disabled, unindexed input object with the text "Loading...", to be
replaced with the _real_ input element after the content is loaded.

This provides the correct appearance and spacing so the content doesn't jiggle about between the
start of loading and the SearchSelect element being finalized.  It was visually distracting and
unappealing.
- Add a unit test to ensure the "Loading..." element is displayed correctly before data arrives
- Demo how to mock a `fetchObjects()` call in testing. Very cool.
- Make distinguishing rule sets for code, tests, and scripts in nightmare mode
- In SearchSelect, Move the `styles()` declaration to the top of the class for consistency.

- To test for the FLOUC issue in SearchSelect.

This is both an exercise in mocking @BeryJu's `fetchObjects()` protocol, and shows how we can unit
test generic components that render API objects.
…select-table

* web/bug/search-select-flouc-issue:
  web: test for flash of unstructured content
  web: comment on state management in API layer, move file to point to correct component under test.
  web: fix Flash of Unstructured Content while SearchSelect is loading from the backend
Mostly these tests assert that the table renders and that the content we give it
is where we expect it to be after sorting. For select tables, it also asserts that
the overall value of the table is what we expect it to be when we click on a
single row, or on the "select all" button.
* main:
  website/docs: cve release notes (#11026)
  security: fix CVE-2024-42490 (#11022)
  web: bump API Client version (#11021)
  providers/scim: optimize sending all members within a group (#9968)
  providers/scim: add API endpoint to sync single user (#8486)
  web: bump chromedriver from 127.0.3 to 128.0.0 in /tests/wdio (#11017)
  web: dual-select uses, part 2: dual-select harder (#9377)
  web: fix flash of unstructured content, add tests for it (#11013)
  core: bump drf-orjson-renderer from 1.7.2 to 1.7.3 (#11015)
  core: bump github.com/gorilla/sessions from 1.3.0 to 1.4.0 (#11002)
  website/docs: Correct the forward authentication configuration template for Caddy (#11012)
Includes documentation updates and better tests for select-table.
…manipulate test DOMs directly in a browser.exec call so they run in the proper context and be await()ed properly
* main: (30 commits)
  website/docs: prepare release notes for 2024.8 (#11011)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#11070)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#11071)
  web: bump mermaid from 10.9.1 to 11.0.2 in /web (#11066)
  core: bump github.com/jellydator/ttlcache/v3 from 3.2.0 to 3.2.1 (#11059)
  Fix incorrect size redefinition for Discord avatar acquisition code. (#11050)
  core, web: update translations (#11051)
  website: bump micromatch from 4.0.5 to 4.0.8 in /website (#11052)
  core: bump django-pglock from 1.5.1 to 1.6.0 (#11058)
  core: bump goauthentik.io/api/v3 from 3.2024063.13 to 3.2024064.1 (#11060)
  core: bump github.com/prometheus/client_golang from 1.20.1 to 1.20.2 (#11061)
  web: bump the swc group across 2 directories with 11 updates (#11062)
  web: bump tslib from 2.6.3 to 2.7.0 in /web (#11063)
  web: bump @eslint/js from 9.9.0 to 9.9.1 in /web (#11064)
  web: bump syncpack from 12.4.0 to 13.0.0 in /web (#11065)
  web: bump @goauthentik/api from 2024.6.3-1724337552 to 2024.6.3-1724414734 in /web/sfe (#11067)
  web: Provide tests for the aggregate cards, fix a few minor things (#9744)
  enterprise: fix license status progress bar (#11048)
  root: backport version bump (#11045)
  web/flows: update flow background (#11044)
  ...
* main: (92 commits)
  internal: fix go paginator not setting page correctly (#11253)
  core: bump google-api-python-client from 2.143.0 to 2.144.0 (#11241)
  core: bump twilio from 9.2.4 to 9.3.0 (#11242)
  core: bump github.com/prometheus/client_golang from 1.20.2 to 1.20.3 (#11243)
  core: bump ruff from 0.6.3 to 0.6.4 (#11244)
  core: bump pydantic from 2.8.2 to 2.9.0 (#11245)
  core: bump msgraph-sdk from 1.5.4 to 1.6.0 (#11246)
  web: bump the rollup group across 2 directories with 1 update (#11248)
  core: fix missing argument name escaping for property mapping (#11231)
  providers/ldap: rework search_group migration to work with read replicas (#11228)
  core, web: update translations (#11220)
  website: bump postcss from 8.4.44 to 8.4.45 in /website (#11221)
  core: bump golang.org/x/oauth2 from 0.22.0 to 0.23.0 (#11222)
  core: bump django-model-utils from 4.5.1 to 5.0.0 (#11223)
  web: bump @changesets/cli from 2.27.7 to 2.27.8 in /web (#11224)
  web: bump @types/node from 22.5.3 to 22.5.4 in /web (#11225)
  web/admin: improve error handling (#11212)
  providers/ldap: fix incorrect permission check for search access (#11217)
  web/admin: fix missing Sync object button SCIM Provider (#11211)
  website/docs: add note about terraform provider (#11206)
  ...
* main: (25 commits)
  web: bump rapidoc from 9.3.4 to 9.3.5 in /web (#11410)
  website: bump dompurify from 3.0.6 to 3.1.6 in /website (#11402)
  website: bump @types/react from 18.3.5 to 18.3.6 in /website (#11405)
  core: bump goauthentik.io/api/v3 from 3.2024081.1 to 3.2024082.1 (#11406)
  web: bump the storybook group across 1 directory with 7 updates (#11408)
  web: bump typescript-eslint from 8.5.0 to 8.6.0 in /tests/wdio (#11409)
  web: bump typescript-eslint from 8.5.0 to 8.6.0 in /web (#11411)
  web: bump mermaid from 11.2.0 to 11.2.1 in /web (#11412)
  website/docs: upgrade: fix helm command (#11403)
  web: bump API Client version (#11396)
  release: 2024.8.2 (#11395)
  website/docs: prepare release notes for 2024.8.2 (#11394)
  core: bump paramiko from 3.4.1 to 3.5.0 (#11388)
  stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#11383)
  core, web: update translations (#11375)
  core: bump django-pglock from 1.6.1 to 1.6.2 (#11389)
  website: bump postcss from 8.4.45 to 8.4.47 in /website (#11390)
  core: bump ruff from 0.6.4 to 0.6.5 (#11391)
  core: bump psycopg from 3.2.1 to 3.2.2 (#11392)
  web: bump @floating-ui/dom from 1.6.10 to 1.6.11 in /web (#11393)
  ...
Got the binding editor in.  The tests complete.  Removed sonarjs.
Copy link

netlify bot commented Sep 20, 2024

Deploy Preview for authentik-docs canceled.

Name Link
🔨 Latest commit 59b74e9
🔍 Latest deploy log https://app.netlify.com/sites/authentik-docs/deploys/672506d15ca7660008b6fab1

Copy link

netlify bot commented Sep 20, 2024

Deploy Preview for authentik-storybook ready!

Name Link
🔨 Latest commit 59b74e9
🔍 Latest deploy log https://app.netlify.com/sites/authentik-storybook/deploys/672506d1828b980008793657
😎 Deploy Preview https://deploy-preview-11462--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 Sep 20, 2024

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
1591 1 1590 1
View the top 1 failed tests by shortest run time
authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI test_create_transactional_bindings
Stack Traces | 0.372s run time
self = <unittest.case._Outcome object at 0x7f41db06df70>
test_case = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
subTest = False

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

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

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
result = <TestCaseFunction test_create_transactional_bindings>

    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.7................../x64/lib/python3.12/unittest/case.py:634: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
method = <bound method TestTransactionalApplicationsAPI.test_create_transactional_bindings of <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>>

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

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

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>

    def test_create_transactional_bindings(self):
        """Test transactional Application + provider creation"""
        assign_perm("authentik_policies.add_policybinding", self.user)
        self.client.force_login(self.user)
        uid = generate_id()
        group = Group.objects.create(name=generate_id())
        authorization_flow = create_test_flow()
        response = self.client.put(
            reverse("authentik_api:core-transactional-application"),
            data={
                "app": {
                    "name": uid,
                    "slug": uid,
                },
                "provider_model": "authentik_providers_oauth2.oauth2provider",
                "provider": {
                    "name": uid,
                    "authorization_flow": str(authorization_flow.pk),
                },
                "policy_bindings": [{"group": group.pk, "order": 0}],
            },
        )
>       self.assertJSONEqual(response.content.decode(), {"applied": True, "logs": []})

.../core/tests/test_transactional_applications_api.py:70: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
raw = '{"provider":{"invalidation_flow":["This field is required."]}}'
expected_data = {'applied': True, 'logs': []}, msg = None

    def assertJSONEqual(self, raw, expected_data, msg=None):
        """
        Assert that the JSON fragments raw and expected_data are equal.
        Usual JSON non-significant whitespace rules apply as the heavyweight
        is delegated to the json library.
        """
        try:
            data = json.loads(raw)
        except json.JSONDecodeError:
            self.fail("First argument is not valid JSON: %r" % raw)
        if isinstance(expected_data, str):
            try:
                expected_data = json.loads(expected_data)
            except ValueError:
                self.fail("Second argument is not valid JSON: %r" % expected_data)
>       self.assertEqual(data, expected_data, msg=msg)

../../../..../pypoetry/virtualenvs/authentik-xvtLQ9eE-py3.12/lib/python3.12.../django/test/testcases.py:922: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
first = {'provider': {'invalidation_flow': ['This field is required.']}}
second = {'applied': True, 'logs': []}, 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.12.7................../x64/lib/python3.12/unittest/case.py:885: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
d1 = {'provider': {'invalidation_flow': ['This field is required.']}}
d2 = {'applied': True, 'logs': []}, msg = None

    def assertDictEqual(self, d1, d2, msg=None):
        self.assertIsInstance(d1, dict, 'First argument is not a dictionary')
        self.assertIsInstance(d2, dict, 'Second argument is not a dictionary')
    
        if d1 != d2:
            standardMsg = '%s != %s' % _common_shorten_repr(d1, d2)
            diff = ('\n' + '\n'.join(difflib.ndiff(
                           pprint.pformat(d1).splitlines(),
                           pprint.pformat(d2).splitlines())))
            standardMsg = self._truncateMessage(standardMsg, diff)
>           self.fail(self._formatMessage(msg, standardMsg))

.../hostedtoolcache/Python/3.12.7................../x64/lib/python3.12/unittest/case.py:1184: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <authentik.core.tests.test_transactional_applications_api.TestTransactionalApplicationsAPI testMethod=test_create_transactional_bindings>
msg = "{'provider': {'invalidation_flow': ['This field is required.']}} != {'applied': True, 'logs': []}\n- {'provider': {'invalidation_flow': ['This field is required.']}}\n+ {'applied': True, 'logs': []}"

    def fail(self, msg=None):
        """Fail immediately, with the given message."""
>       raise self.failureException(msg)
E       AssertionError: {'provider': {'invalidation_flow': ['This field is required.']}} != {'applied': True, 'logs': []}
E       - {'provider': {'invalidation_flow': ['This field is required.']}}
E       + {'applied': True, 'logs': []}

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

To view individual test run time comparison to the main branch, go to the Test Analytics Dashboard

Copy link
Contributor

github-actions bot commented Sep 20, 2024

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-ec020955a16da695260b3ff661c2579ffd0ea2b9
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s

For arm64, use these values:

AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
AUTHENTIK_TAG=gh-ec020955a16da695260b3ff661c2579ffd0ea2b9-arm64
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-ec020955a16da695260b3ff661c2579ffd0ea2b9

For arm64, use these values:

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-ec020955a16da695260b3ff661c2579ffd0ea2b9-arm64

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

* web/element/ak-select-table:
  web: repeat is needed to make sure sub-elements move around correctly. Map does not do full tracking.
  Provide unit test accessibility to Firefox and Safari; wrap calls to manipulate test DOMs directly in a browser.exec call so they run in the proper context and be await()ed properly
  web: finalize testing for tables
  web: added basic unit testing to API-free tables
  web: interim commit of the basic sortable & selectable table.
  web: test for flash of unstructured content
  web: comment on state management in API layer, move file to point to correct component under test.
  web: fix Flash of Unstructured Content while SearchSelect is loading from the backend
…'delete'. TODO: Fix error reporting on home page, the edit button is ugly, and the height is off somehow, but I'm not yet sure how. I just know it bugs my eyes.
especially since we'll be using the wizard as default in the future, it shouldn't be superuser only

Signed-off-by: Jens Langhammer <[email protected]>
… into web/policy-wizard-3

* origin/core/app-transactional/bindings: (47 commits)
  improve permission checks
  core: add support to set policy bindings in transactional endpoint
  web/admin: fix Authentication flow being required (#11496)
  web: bump the wdio group across 2 directories with 5 updates (#11494)
  web: bump turnstile-types from 1.2.2 to 1.2.3 in /web (#11495)
  web: bump the swc group across 2 directories with 11 updates (#11493)
  web: bump the eslint group across 2 directories with 5 updates (#11492)
  web: bump the storybook group across 1 directory with 7 updates (#11491)
  core: bump bandit from 1.7.9 to 1.7.10 (#11485)
  web: bump the rollup group across 2 directories with 3 updates (#11487)
  web: bump @types/node from 22.5.5 to 22.6.1 in /web (#11490)
  website/docs: use a more consistent version requirement notice (#11400)
  website/docs: clarify API browser access (#11373)
  website/integrations: Glitchtip: update redirect URL (#11438)
  web: bump knip from 5.30.4 to 5.30.5 in /web (#11479)
  fix: proxy provider - docker traefik label (#11460)
  website: the requirements for Go and Node required updating. (#11419)
  web: bump the esbuild group across 1 directory with 3 updates (#11470)
  web: bump @sentry/browser from 8.30.0 to 8.31.0 in /web in the sentry group across 1 directory (#11478)
  web: bump the eslint group across 2 directories with 1 update (#11469)
  ...
* main: (146 commits)
  website: bump @types/react from 18.3.8 to 18.3.9 in /website (#11502)
  core: bump debugpy from 1.8.5 to 1.8.6 (#11503)
  core: bump google-api-python-client from 2.146.0 to 2.147.0 (#11504)
  web: bump @types/node from 22.6.1 to 22.7.0 in /web (#11505)
  core, web: update translations (#11500)
  sources/ldap: fix mapping check, fix debug endpoint (#11442)
  web/admin: fix Authentication flow being required (#11496)
  web: bump the wdio group across 2 directories with 5 updates (#11494)
  web: bump turnstile-types from 1.2.2 to 1.2.3 in /web (#11495)
  web: bump the swc group across 2 directories with 11 updates (#11493)
  web: bump the eslint group across 2 directories with 5 updates (#11492)
  web: bump the storybook group across 1 directory with 7 updates (#11491)
  core: bump bandit from 1.7.9 to 1.7.10 (#11485)
  web: bump the rollup group across 2 directories with 3 updates (#11487)
  web: bump @types/node from 22.5.5 to 22.6.1 in /web (#11490)
  website/docs: use a more consistent version requirement notice (#11400)
  website/docs: clarify API browser access (#11373)
  website/integrations: Glitchtip: update redirect URL (#11438)
  web: bump knip from 5.30.4 to 5.30.5 in /web (#11479)
  fix: proxy provider - docker traefik label (#11460)
  ...
- Replace `th` with `td` in `thead` components. Because Patternfly.
- Add @BeryJu's styling to the tables, which make it much better looking
- Add policy bindings to the application wizard

- Restructures the Wizard base code.
  - ak-wizard-steps holds the steps and listens for NavigationRequest events to move
    from one step to the next.
  - WizardStep is a base class (no component registration provided) that provides the *whole frame*,
    not just the form.  It receives the navigation content for the sidebar from ak-wizard-steps,
    and provides the styling for the header, footer, sidebar, and main form.  It has abstractions
    for `buttons`, `renderMain()`, `handleButton()`, `handleEnable()`, in a section well-marked as
    "Public API".  Steps inherit from this class.

Conceptually:

- A wizard is a series of pages ("steps") with a distinct beginning and end, linked in a series,
  to complete a task.
- Later steps in the series are inaccessible until an earlier steps has granted access to it.
- Access is predicated on the earlier step being complete and valid. The developer is responsible
  for determining what "complete and valid" means.
- The series is visible, giving the customer a sense of how much effort is needed to complete the
  task.
- A parent object maintains (and can modify as needed) the list of steps. It *can* maintain the
  information being collected from the user. Alternatively, that information can be kept in each
  step.

Details:

- Keeping with the Lit paradigm, "requests to change the system flow up, information changed by
  valid requests flows down."
- The information flows up using events: WizardNavigation, WizardUpdate, WizardClose.
- The information flows down using properties.

- ak-application-wizard-main holds the list of steps, providing a unique slot name for each.
  - It maintains the ApplicationWizardState object.
- ApplicationWizardStep inherits from WizardStep and provides:
  - A means of extraction information from forms
  - A convenience method for updating the ApplicationWizardState object, enabling future steps, and
    navigating to a future step, in the correct order.
  - A method for cleaning error from the error reporting mechanism as the user navigates from an
    error-handling state.
  - The title, description, and cancelability of the wizard.
- Steps:
  - step: Handles the application. A good starting point for understanding the point of
    the Wizard.  Check the `handleButton()` method to understand how we enable or disable access to
    future steps.
  - provider-choice: Just a list. Shows validation without the form.
  - provider: Uses a *very* esoteric Lit feature, `unsafeStaticTag`, which enables
    the display to show anything that conforms to the expectations of ApplicationWizardProviderForm.
    - ApplicationWizardProviderForm repeats some of the base of ApplicationWizardStep, but allows us
      to provide multiple variants on a single form without having to create separate steps for each
      form.
    - The forms (`provider-for-ldap`, `provider-for-radius`) are therefore *just* the form and any
      fetchers needed to populate it.
  - bindings: Shows the table of bindings.  Has a custom display for "This table is empty."
  - edit-binding: Showcase for the `SearchSelectEZ` configuration format. Has an override on the
    `handleButton` feature to figure out which binding is about to be overridden. Is also a
    `.hidden` page; it doesn't show up on the navigation sidebar, as is only navigable-to by buttons
    not associated with the button bar at the bottom.
  - submit: Has a lot of machinery of state: Reviewing with errors, reviewing without errors,
    running submission, and success. Uses `ts-pattern` a lot to make sure the state/request pairs
    make sense.

The key insight is that, even though a wizard is a series in order, that order can't be simply
maintained in a list. The parent needs various strategies for swapping pages in and out of the
sequence, while still maintaining a coherent idea of "flow" and providing the visual cues the user
needs to feel confident that the work can be completed and completed quickly. The entire mechanism
for using an array and index to navigate, with index numbering, blocked the implementation of the
bindings pages.

One thing led to another.  *Sigh*  Really wish this hadn't been as much of a mess as it turned out.
The end result is pretty good, though.  Definitely re-usable.

One important feature to note is that the wizard is *not* tied to the ModalButton object; it's
simply embedded in a modal as-needed.  This allows us to use wizards in other places, such as just
being in a DIV, or just a page on its own.
@kensternberg-authentik kensternberg-authentik marked this pull request as ready for review September 26, 2024 17:57
@kensternberg-authentik kensternberg-authentik changed the title Web/policy wizard 3 web: add application bindings to the application wizard Oct 7, 2024
* main: (68 commits)
  core: extract object matching from flow manager (#11458)
  admin: store version history (#11520)
  web: bump API Client version (#11706)
  providers/oauth2: add initial JWE support (#11344)
  core, web: update translations (#11703)
  tests/e2e: add forward auth e2e test (#11374)
  web/admin: fix duplicate flow labels (#11689)
  providers/saml: fix incorrect ds:Reference URI (#11699)
  website/docs: Fix websocket default config for nginx proxy manager (#11621)
  core, web: update translations (#11692)
  core: bump uvicorn from 0.31.1 to 0.32.0 (#11693)
  core: bump github.com/prometheus/client_golang from 1.20.4 to 1.20.5 (#11694)
  website/docs: add missing file to sidebar (#11695)
  website/docs: rewrote too long sentence (#11696)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#11697)
  translate: Updates for file web/xliff/en.xlf in fr (#11698)
  stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#11683)
  core, web: update translations (#11682)
  core: bump github.com/getsentry/sentry-go from 0.29.0 to 0.29.1 (#11684)
  core: bump github.com/redis/go-redis/v9 from 9.6.1 to 9.6.2 (#11685)
  ...
…unately, this does not solve the general problem that we have a UX issue with which stage bindings to show where now that we've introduced the Invalidation Stage.
## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <[email protected]>
* main: (43 commits)
  core, web: update translations (#11858)
  web/admin: fix code-based MFA toggle not working in wizard (#11854)
  sources/kerberos: add kiprop to ignored system principals (#11852)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#11846)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#11845)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#11847)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#11848)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans (#11849)
  translate: Updates for file web/xliff/en.xlf in it (#11850)
  website: 2024.10 Release Notes (#11839)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#11814)
  core, web: update translations (#11821)
  core: bump goauthentik.io/api/v3 from 3.2024083.13 to 3.2024083.14 (#11830)
  core: bump service-identity from 24.1.0 to 24.2.0 (#11831)
  core: bump twilio from 9.3.5 to 9.3.6 (#11832)
  core: bump pytest-randomly from 3.15.0 to 3.16.0 (#11833)
  website/docs: Update social-logins github (#11822)
  website/docs: remove � (#11823)
  lifecycle: fix kdc5-config missing (#11826)
  website/docs: update preview status of different features (#11817)
  ...
* web/admin-default-invalidations: (92 commits)
  admin/web: the default invalidation flows for LDAP and Radius are different from the others.
  web/admin: provide default invalidation flows for LDAP provider.
  core, web: update translations (#11858)
  web/admin: fix code-based MFA toggle not working in wizard (#11854)
  sources/kerberos: add kiprop to ignored system principals (#11852)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#11846)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#11845)
  translate: Updates for file web/xliff/en.xlf in zh_CN (#11847)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#11848)
  translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans (#11849)
  translate: Updates for file web/xliff/en.xlf in it (#11850)
  website: 2024.10 Release Notes (#11839)
  translate: Updates for file web/xliff/en.xlf in zh-Hans (#11814)
  core, web: update translations (#11821)
  core: bump goauthentik.io/api/v3 from 3.2024083.13 to 3.2024083.14 (#11830)
  core: bump service-identity from 24.1.0 to 24.2.0 (#11831)
  core: bump twilio from 9.3.5 to 9.3.6 (#11832)
  core: bump pytest-randomly from 3.15.0 to 3.16.0 (#11833)
  website/docs: Update social-logins github (#11822)
  website/docs: remove � (#11823)
  ...
…1861)

* web: Add InvalidationFlow to Radius Provider dialogues

## What

- Bugfix: adds the InvalidationFlow to the Radius Provider dialogues
  - Repairs: `{"invalidation_flow":["This field is required."]}` message, which was *not* propagated
    to the Notification.
- Nitpick: Pretties `?foo=${true}` expressions: `s/\?([^=]+)=\$\{true\}/\1/`

## Note

Yes, I know I'm going to have to do more magic when we harmonize the forms, and no, I didn't add the
Property Mappings to the wizard, and yes, I know I'm going to have pain with the *new* version of
the wizard. But this is a serious bug; you can't make Radius servers with *either* of the current
dialogues at the moment.

* web/admin: provide default invalidation flows for LDAP provider.

* admin/web: the default invalidation flows for LDAP and Radius are different from the others.
* website/docs: 2024.8.4 release notes

Signed-off-by: Jens Langhammer <[email protected]>

* typo

Signed-off-by: Jens Langhammer <[email protected]>

---------

Signed-off-by: Jens Langhammer <[email protected]>
* release: 2024.10.0-rc1

* root: `bumpversion` 2024.10 (#11865)

release: 2024.10.0
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
…ral (#11800)

* restructure

* tweak

* fix header

* added more definitions

* jens excellent idea

* restructure the Layouts content

* tweaks

* links fix

* links still

* fighting links and cache

* argh links

* ditto

* remove link

* anothe link

* Jens' edit

* listed default flows set by brand

* add links back

* tweaks

* used import for list

* tweak

* rewrite some stuff

Signed-off-by: Jens Langhammer <[email protected]>

* format

Signed-off-by: Jens Langhammer <[email protected]>

* mangled rebase, fixed

* bump

---------

Signed-off-by: Jens Langhammer <[email protected]>
Co-authored-by: Tana M Berry <[email protected]>
Co-authored-by: Jens Langhammer <[email protected]>
…1876)

Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2024083.14 to 3.2024100.1.
- [Release notes](https://github.com/goauthentik/client-go/releases)
- [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
- [Commits](goauthentik/client-go@v3.2024083.14...v3.2024100.1)

---
updated-dependencies:
- dependency-name: goauthentik.io/api/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [selenium](https://github.com/SeleniumHQ/Selenium) from 4.25.0 to 4.26.0.
- [Release notes](https://github.com/SeleniumHQ/Selenium/releases)
- [Commits](SeleniumHQ/selenium@selenium-4.25.0...selenium-4.26.0)

---
updated-dependencies:
- dependency-name: selenium
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.7 to 6.6.0.
- [Commits](indutny/elliptic@v6.5.7...v6.6.0)

---
updated-dependencies:
- dependency-name: elliptic
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* main:
  website: bump elliptic from 6.5.7 to 6.6.0 in /website (#11869)
  core: bump selenium from 4.25.0 to 4.26.0 (#11875)
  core: bump goauthentik.io/api/v3 from 3.2024083.14 to 3.2024100.1 (#11876)
  website/docs: add info about invalidation flow, default flows in general (#11800)
  website: fix docs redirect (#11873)
  website: remove RC disclaimer for version 2024.10 (#11871)
  website: update supported versions (#11841)
  web: bump API Client version (#11870)
  root: backport version bump 2024.10.0 (#11868)
  website/docs: 2024.8.4 release notes (#11862)
  web/admin: provide default invalidation flows for LDAP and Radius (#11861)
…is is an intermediate fix to get the tests passing. It will probably be mooted with the next revision.*
@kensternberg-authentik kensternberg-authentik changed the base branch from main to web/update-provider-forms-for-invalidation November 1, 2024 16:53
@kensternberg-authentik kensternberg-authentik changed the title web: add application bindings to the application wizard web/admin: add application bindings to the application wizard Nov 1, 2024
@BeryJu BeryJu added the deploy_me Deploy the PR changes on a test environment label Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deploy_me Deploy the PR changes on a test environment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants