Skip to content

Web/maintenance/explicit model endpoints#22897

Open
kensternberg-authentik wants to merge 2 commits into
web/maintenance/eliminates-even-the-toughest-stainsfrom
web/maintenance/explicit-model-endpoints
Open

Web/maintenance/explicit model endpoints#22897
kensternberg-authentik wants to merge 2 commits into
web/maintenance/eliminates-even-the-toughest-stainsfrom
web/maintenance/explicit-model-endpoints

Conversation

@kensternberg-authentik
Copy link
Copy Markdown
Contributor

web/maintenance: eliminate boilerplate methods from ModelForm

What

Provide an alternative syntax for defining the load/create/update methods in ModelForm.

Provide a default message for getSuccessMessage: Successfully created or Successfully updated plus the verboseName, if defined.

The old syntax still exists, and is required for a number of complicated and crusty forms with multiple fetches or unusual return values.

getSuccessMessage() can still be overridden, if you feel it’s necessary.

How

Retrieve / Create / Update

This builds on the insights from the aki() authentik API wrapper: find a way to wrap boilerplate in a function. Every ModelForm supplies three methods: load(), send(), and getSuccessMessage(). send() is secretly two different methods in a trenchcoat: it’s create() and update(), depending on whether or not the object has an instancePk.

This commit adds a new field to ModelForm: endpoints?, which contains fields for load, create, and update; these contain only the minimal code needed to perform these duties. For example, the FlowForm’s endpoints look like this:

   protected endpoints = {
       load: (slug: string) => aki(FlowsApi).flowsInstancesRetrieve({ slug }),
       create: (flowRequest: Flow) => aki(FlowsApi).flowsInstancesCreate({ flowRequest }),
       update: (slug: string, flowRequest: Flow) =>
           aki(FlowsApi).flowsInstancesUpdate({ slug, flowRequest }),
   };

New concrete implementations of load and send in FlowForm, if not overridden (as they typically are now), look for endpoints.load, endpoints.create, and (if instancePk is set) endpoints.update, and call the functions defined in endpoints, providing the same functionality as before. Both calls have exception handlers for “Neither overridden nor properly parameterized”, preserving the existing error condition semantics.

Success… messages.

getSuccessMessage() was just a funny fix: every form defines a verboseName; it exists to populate this message: An error occurred while loading ${this.verboseName}. That’s it. That’s all it does.

And then every form implements this stanza:

    public override getSuccessMessage(): string {
        return this.instance
            ? msg("Successfully updated flow.")
            : msg("Successfully created flow.");
    }

So I provided a better default in ModelForm.

    public override getSuccessMessage() {
        if (!this.verboseName) return super.getSuccessMessage();
        return this.instancePk === null
            ? msg(str`Successfully created ${this.verboseName}`)
            : msg(str`Successfully updated ${this.verboseName}`);
    }

Define the verboseName and don’t worry, be happy:

Checklist

  • [🌤️] The project has been linted, built, and tested (make all)
  • [🌤️] The documentation has been updated and formatted (make docs)

## What

Provide an alternative syntax for defining the load/create/update methods in ModelForm.

Provide a default message for `getSuccessMessage`: `Successfully created` or `Successfully updated` plus the verboseName, if defined.

The old syntax still exists, and is required for a number of complicated and crusty forms with multiple fetches or unusual return values.

`getSuccessMessage()` can still be overridden, if you feel it’s necessary.

## How

### Retrieve / Create / Update

This builds on the insights from the `aki()` authentik API wrapper: find a way to wrap boilerplate in a function. Every ModelForm supplies three methods: `load()`, `send()`, and `getSuccessMessage()`. `send()` is secretly two different methods in a trenchcoat: it’s `create()` and `update()`, depending on whether or not the object has an instancePk.

This commit adds a new field to ModelForm: `endpoints?`, which contains fields for `load`, `create`, and `update`; these contain *only* the minimal code needed to perform these duties. For example, the FlowForm’s endpoints look like this:

       protected endpoints = {
           load: (slug: string) => aki(FlowsApi).flowsInstancesRetrieve({ slug }),
           create: (flowRequest: Flow) => aki(FlowsApi).flowsInstancesCreate({ flowRequest }),
           update: (slug: string, flowRequest: Flow) =>
               aki(FlowsApi).flowsInstancesUpdate({ slug, flowRequest }),
       };

New concrete implementations of `load` and `send` in FlowForm, if not overridden (as they typically are now), look for `endpoints.load`, `endpoints.create`, and (if `instancePk` is set) `endpoints.update`, and call the functions defined in `endpoints`, providing the same functionality as before. Both calls have exception handlers for “Neither overridden nor properly parameterized”, preserving the existing error condition semantics.

### Success… messages.

`getSuccessMessage()` was just a funny fix: every form defines a `verboseName`; it exists to populate this message: `An error occurred while loading ${this.verboseName}.` That’s it. That’s all it does.

And then every form implements this stanza:

        public override getSuccessMessage(): string {
            return this.instance
                ? msg("Successfully updated flow.")
                : msg("Successfully created flow.");
        }

So I provided a better default in ModelForm.

        public override getSuccessMessage() {
            if (!this.verboseName) return super.getSuccessMessage();
            return this.instancePk === null
                ? msg(str`Successfully created ${this.verboseName}`)
                : msg(str`Successfully updated ${this.verboseName}`);
        }

Define the verboseName and don’t worry, be happy:
@kensternberg-authentik kensternberg-authentik changed the base branch from main to web/maintenance/eliminates-even-the-toughest-stains June 5, 2026 21:14
@netlify
Copy link
Copy Markdown

netlify Bot commented Jun 5, 2026

Deploy Preview for authentik-storybook ready!

Name Link
🔨 Latest commit 2ffcbc3
🔍 Latest deploy log https://app.netlify.com/projects/authentik-storybook/deploys/6a233c2a1a4c3a00085cd2a1
😎 Deploy Preview https://deploy-preview-22897--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
Copy link
Copy Markdown

netlify Bot commented Jun 5, 2026

Deploy Preview for authentik-integrations ready!

Name Link
🔨 Latest commit bfde6f3
🔍 Latest deploy log https://app.netlify.com/projects/authentik-integrations/deploys/6a233c9bfcb63e0008fc7c16
😎 Deploy Preview https://deploy-preview-22897--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.

…to web/maintenance/explicit-model-endpoints

* web/maintenance/eliminates-even-the-toughest-stains:
  ci: bump taiki-e/install-action from 2.81.1 to 2.81.2 in /.github/actions/setup (#22884)
  website/integrations: add Atlantis integration (#22888)
  website/docs: Document WebAuthn device restrictions (#22867)
  web/admin: fix Docker outpost integration form CA Cert filter (#22863)
  web: bump @sentry/browser from 10.54.0 to 10.55.0 in /web in the sentry group across 1 directory (#22873)
  core: bump sentry-sdk from 2.60.0 to 2.61.0 (#22875)
  core: bump google-api-python-client from 2.196.0 to 2.197.0 (#22876)
  core: bump kubernetes from 36.0.0 to 36.0.2 (#22879)
  web: bump the bundler group across 1 directory with 3 updates (#22881)
  core: bump debugpy from 1.8.20 to 1.8.21 (#22880)
  ci: bump github/codeql-action from 4.36.0 to 4.36.1 (#22882)
  ci: bump AndreKurait/docker-cache from 0.6.0 to 0.7.0 in /.github/actions/setup (#22883)
@netlify
Copy link
Copy Markdown

netlify Bot commented Jun 5, 2026

Deploy Preview for authentik-docs ready!

Name Link
🔨 Latest commit bfde6f3
🔍 Latest deploy log https://app.netlify.com/projects/authentik-docs/deploys/6a233c9be7899d00096f29c9
😎 Deploy Preview https://deploy-preview-22897--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.

@kensternberg-authentik kensternberg-authentik marked this pull request as ready for review June 5, 2026 21:17
@kensternberg-authentik kensternberg-authentik requested a review from a team as a code owner June 5, 2026 21:17
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

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-2ffcbc37c7d2c7413fa5bb55b88e3be2ac0308fd
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-2ffcbc37c7d2c7413fa5bb55b88e3be2ac0308fd

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

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