-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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: Application wizard v2 with tests #7004
Merged
kensternberg-authentik
merged 135 commits into
main
from
application-wizard-2-with-api-and-tests
Oct 18, 2023
Merged
web: Application wizard v2 with tests #7004
kensternberg-authentik
merged 135 commits into
main
from
application-wizard-2-with-api-and-tests
Oct 18, 2023
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is a pretty good result. By using the LightDOM setting, this provides the existing Authentik form manager with access to the ak-form-horizontal-element components without having to do any cross-border magic. It's not ideal, and it shows up just how badly we've got patternfly splattered everywhere, but the actual results are remarkable. The patterns for text, switch, radio, textarea, file, and even select are smaller and easier here. I'm still noodling on what an unspread search-select element would look like. It's just dependency injection, so it ought to be as straightforward as that.
I become frustrated with my inability to make any progress on this project, so I decided to reach for a tool that I consider highly reliable but also incredibly time-consuming and boring: test driven development. In this case, I wrote a story about how I wanted to see the first page rendered: just put the HTML tag, completely unadorned, that will handle the first page of the wizard. Then, add an event handler that will send the updated content to some parent object, since what we really want is to orchestrate the state of the user's input with a centralized location. Then, rather than fiddling with the attributes and properties of the various pages, I wanted them to be able to "look up" the values they want, much as we'd expect a standalone form to be able to pull its values from the server, so I added a context object that receives the update event and incorporates the new knowledge about the state of the process into itself. The result is surprisingly satisfying: the first page renders cleanly, displays the content that we want, and as we fiddle with, we can *watch in real time* as the results of the context are updated and retransmitted to all receiving objects. And the sending object gets the results so it re-renders, but it ends up looking the same as it was before the render.
…s working, but there is a bug: the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend their events as standard `input` events, and that actually seems to work well; the browser is decorating it with the right target, with the right `name` attribute, and since we have good definitions of the `value` as a string (the real value of any search object is its UUID4), that works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs), and the latter has flags for "use the first one if it's the only one" and "allow the display of keyless certificates." Not sure why `state()` is blocking the transmission of typing information from the typed element to the context handler, but it's a bug in the typechecker, and it's not a problem so far.
…s working, but there is a bug: the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend their events as standard `input` events, and that actually seems to work well; the browser is decorating it with the right target, with the right `name` attribute, and since we have good definitions of the `value` as a string (the real value of any search object is its UUID4), that works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs), and the latter has flags for "use the first one if it's the only one" and "allow the display of keyless certificates." Not sure why `state()` is blocking the transmission of typing information from the typed element to the context handler, but it's a bug in the typechecker, and it's not a problem so far.
Because radio inputs are actually multiples, the events handling for radio is... wonky. If we want our `<ak-radio>` component to be a unitary event dispatcher, saying "This is the element selected," we needed to do more than what was currently being handled. I've intercepted the events that we care about and have placed them into a controller that dictates both the setting and the re-render of the component. This makes it "controlled" (to use the Angular/React/Vue) language and depends on Lit's reactiveElement lifecycle to work, rather than trust the browser, but the browser's experience with respect to the `<input type=radio` is pretty bad: both input elements fire events, one for "losing selection" and one for "gaining selection". That can be very confusing to handle, so we funnel them down in our aggregate radio element to a single event, "selection changed". As a quality-of-life measure, I've also set the label to be unselectable; this means that a click on the label will trigger the selection event, and a long click will not disable selection or confuse the selection event generator.
…he body. This isn't really a very good hack; what it does is say that every story is responsible for hacking its theme into the parent. This is very annoying, but it does mean that we can at least show our components in the best light.
1. Fixed `eventEmitter` so that if the detail object is a scalar, it will not attempt to "objectify" it. This was causing a bug where retrofitting the eventEmitter to some older components resulted in a detail of "some" being translated into ['s', 'o', 'm', 'e']. Not what is wanted. 2. Removed the "transitional form" from the existing components; they had a two-step where the web component class was just a wrapper around an independent rendering function. While this worked, it was only to make the case that they *were* independent rendering objects and could be supported with the right web component framework. We're halfway there now; the last step will be to transform the horizontal-element and various input CSS into componentized CSS, the way Patternfly-Elements is currently doing. 3. Fixed the `help` field so that it could take a string or a TemplateResult, and if the latter, don't bother wrapping it in the helper text functionality; just let it be its own thing. This supports the multi-line help of redirectURI as well as the `ak-utils-time-delta` capability. 4. Transform Oauth2ProviderForm to use the new components, to the best of our ability. Also used the `provider = this.wizard.provider` and `provider = this.instance` syntax to make the render function *completely portable*; it's the exact same text that is dropped into... 5. The complete `ak-application-wizard-authentication-by-oauth` component. They're so similar part of me wonders if I could push them both out to a common reference, or a collection of common references. Both components use the PropertyMapping and Sources, and both use the same collection of searches (Crypto, Flow). 6. A Storybook for `ak-application-wizard-authentication-by-oauth`, showing the works working. 7. New mocks for `authorizationFlow`, `propertyMappings`, and `hasJWKs`. This sequence has revealed a bug in the radio control. (It's always the radio control.) If the default doesn't match the current setting, the radio control doesn't behave as expected; it won't change when you fully expect that it should. I'll investigate how to harmonize those tomorrow.
* main: blueprints: prevent duplicate password stage in default flow when using combined identification stage (#6432) website/integrations: cite better (#6431) root: add generated Source docs (#5323) website/docs: add architecture and persistence (#6250) core: bump paramiko from 3.2.0 to 3.3.1 (#6428) website: fix sidebar sizing (#6430) ci: update dependabot labels (#6423) website: fix sidebar layout (#6421)
* main: (36 commits) website/blog: add github user name links (#6468) website/developer-docs: add new template for procedures (#6390) website/blogs: blog to celebrate hackathon (#6457) web/flows: add more stories (#6444) web: bump prettier from 3.0.0 to 3.0.1 in /web (#6465) core: bump debugpy from 1.6.7 to 1.6.8 (#6458) ci: bump peter-evans/create-pull-request from 4 to 5 (#6459) web: bump lit from 2.7.6 to 2.8.0 in /web (#6460) web: bump @fortawesome/fontawesome-free from 6.4.0 to 6.4.2 in /web (#6461) web: bump chart.js from 4.3.2 to 4.3.3 in /web (#6462) web: bump @lit-labs/task from 2.1.2 to 3.0.0 in /web (#6463) web, website: compress images (#6121) core: bump cryptography from 41.0.2 to 41.0.3 (#6456) root: replace builtin psycopg libpq binary implementation with distro… (#6448) website: fix broken links in NewsBar core: bump github.com/getsentry/sentry-go from 0.22.0 to 0.23.0 (#6449) core: bump goauthentik.io/api/v3 from 3.2023061.6 to 3.2023061.7 (#6450) web: bump pyright from 1.1.319 to 1.1.320 in /web (#6451) core: bump ruff from 0.0.281 to 0.0.282 (#6453) core: bump golang from 1.20.6-bullseye to 1.20.7-bullseye (#6454) ...
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit replaces various ad-hoc implementations of the Patternfly Toggle Group HTML with a web component that encapsulates all of the needed behavior and exposes a single API with a single event handler, return the value of the option clicked. The results are: Lots of visual clutter is eliminated. A single link of: ``` <div class="pf-c-toggle-group__item"> <button class="pf-c-toggle-group__button ${this.mode === ProxyMode.Proxy ? "pf-m-selected" : ""}" type="button" @click=${() => { this.mode = ProxyMode.Proxy; }}> <span class="pf-c-toggle-group__text">${msg("Proxy")}</span> </button> </div> <div class="pf-c-divider pf-m-vertical" role="separator"></div> ``` Now looks like: ``` <option value=${ProxyMode.Proxy}>${msg("Proxy")}</option> ``` This also means that the three pages that used the Patternfly Toggle Group could eliminate all of their Patternfly PFToggleGroup needs, as well as the `justify-content: center` extension, which also eliminated the `css` import. The savings aren't as spectacular as I'd hoped: removed 178 lines, but added 123; total savings 55 lines of code. I still count this a win: we need never write another toggle component again, and any bugs, extensions or features we may want to add can be centralized or forked without risking the whole edifice.
…ects Signed-off-by: Jens Langhammer <jens@goauthentik.io>
…to-certeficate-search This commit replaces various ad-hoc implementations of `search-select` for CryptoCertificateKeyPairs with a web component that encapsulates all of the needed behavior and exposes a single API. The results are: Lots of visual clutter is eliminated. A single search of: ```HTML <ak-search-select .fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => { const args: CryptoCertificatekeypairsListRequest = { ordering: "name", hasKey: true, includeDetails: false, }; if (query !== undefined) { args.search = query; } const certificates = await new CryptoApi( DEFAULT_CONFIG, ).cryptoCertificatekeypairsList(args); return certificates.results; }} .renderElement=${(item: CertificateKeyPair): string => { return item.name; }} .value=${(item: CertificateKeyPair | undefined): string | undefined => { return item?.pk; }} .selected=${(item: CertificateKeyPair): boolean => { return this.instance?.tlsVerification === item.pk; }} ?blankable=${true} > </ak-search-select> ``` Now looks like: ```HTML <ak-crypto-certificate-search certificate=${this.instance?.tlsVerification}> </ak-crypto-certificate-search> ``` There are three searches that do not require there to be a valid key with the certificate; these are supported with the boolean property `nokey`; likewise, there is one search (in SAMLProviderForm) that states that if there is no current certificate in the SAMLProvider and only one certificate can be found in the Authentik database, use that one; this is supported with the boolean property `singleton`. These changes replace 382 lines of object-oriented invocations with 36 lines of declarative configuration, and 98 lines for the class. Overall, the code for "find a crypto certificate" has been reduced by 46%. Suggestions for a better word than `singleton` are welcome!
This adds a Storybook for the CryptoCertificateKeypair search, including a mock fetch of the data. In the course of running the tests, we discovered that including the SearchSelect _class_ won't include the customElement declaration unless you include the whole file! Other bugs found: including the CSS from Storybook is different from that of LitElement native, so much so that the adapter needed to be included. FlowSearch had a similar bug. The problem only manifests when building via Webpack (which Storybook uses) and not Rollup, but we should support both in distribution.
* main: web/flows: fix identification stage band color (#6489) providers/proxy: only intercept auth header when a value is set (#6488) web: bump @goauthentik/api from 2023.6.1-1691242648 to 2023.6.1-1691266058 in /web (#6486) providers/proxy: set outpost session cookie to httponly and secure wh… (#6482) web: bump @esbuild/linux-arm64 from 0.18.17 to 0.18.18 in /web (#6483) web/admin: fix user sorting by active field (#6485) web: bump @esbuild/darwin-arm64 from 0.18.17 to 0.18.18 in /web (#6484) web: bump storybook (#6481) web: bump the sentry group in /web with 2 updates (#6480) web: bump API Client version (#6479) api: optimise pagination in API schema (#6478) website/dev-docs: tweaks to template (#6474) website: bump react-tooltip from 5.19.0 to 5.20.0 in /website (#6471) website: bump prettier from 3.0.0 to 3.0.1 in /website (#6472)
preventing the radio from reflecting the default correctly. The observed behavior was that the radio wouldn't "activate" until the item selected during the render pass was clicked on first.
* ak-toggle-group: Bugs found by CI/CD. web: adding a storybook for the ak-toggle-group component web: minor code formatting issue. web: Replace ad-hoc toggle control with ak-toggle-group
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
…roxy 1. Forward Domain Proxy. I wasn't sure if this method was appropriate for the wizard, but Jens says it is. I've added it. 2. In the process of doing so, I decided that the Provider.converter field was overly complexified; I tried too hard to reduce the number of functions I needed to define, but in the process outsourced some of the logic of converting the Wizard's dataset into a property typed request to the `commit` phase, which was inappropriate. All of the logic about a provider, aside from its display, should be here with the code that distinguishes between providers. This commit makes it so. 3. Small CSS fix: the fields inherited from the Proxy provider forms had some unexpected CSS which was causing a bit of a weird indent. That has been rectified.
…2-with-api-and-tests' into application-wizard-2-with-api-and-tests * refs/remotes/origin/application-wizard-2-with-api-and-tests: fix lint errors SCIM Manuel -> SCIM fix label in dark mode
* main: web: bump pyright from 1.1.330 to 1.1.331 in /web (#7143) core: bump golang from 1.21.2-bookworm to 1.21.3-bookworm (#7142) core: bump gitpython from 3.1.35 to 3.1.37 (#7140) core: bump goauthentik.io/api/v3 from 3.2023083.5 to 3.2023083.6 (#7124) website/docs: fix PowerDNS Docker Hub repo name (#7134) website/blog: Fix typo in SCIM post (#7136) providers/proxy: fix redis cookies missing strict path (#7135) web: bump @lit-labs/task from 3.0.2 to 3.1.0 in /web (#7132) web: bump @lit/localize-tools from 0.6.10 to 0.7.0 in /web (#7133) web: bump the eslint group in /tests/wdio with 2 updates (#7128) core: bump structlog from 23.1.0 to 23.2.0 (#7125) core: bump selenium from 4.13.0 to 4.14.0 (#7126) web: bump the eslint group in /web with 2 updates (#7127) web: bump the wdio group in /tests/wdio with 4 updates (#7129)
* main: web: patternfly hints as ak-web-component (#7120) web: fix form default submit handler (#7122) web/admin: add additional Flow info (#7155) tests: fix potential infinite wait in tests spinning up a container (#7153) ci: disable ghcr retention schedule while it's broken (#7154) translate: Updates for file locale/en/LC_MESSAGES/django.po in de (#7151) core: bump golang.org/x/net from 0.16.0 to 0.17.0 (#7148) web: bump the babel group in /web with 5 updates (#7149) core: bump sentry-sdk from 1.31.0 to 1.32.0 (#7150) website: make get started on pricing page go to customer portal (#7147)
* main: web: change 'Attributes' to 'Custom attributes' on Invitation Field (#7145)
There were some HEAVY merge bugs in the translation files. * main: providers/scim: remove preview (#7166) web: bump the wdio group in /tests/wdio with 4 updates (#7160) translate: Updates for file web/xliff/en.xlf in zh_CN (#7162) translate: Updates for file web/xliff/en.xlf in zh-Hans (#7161) translate: Updates for file web/xliff/en.xlf in zh-Hans (#7158) website/docs: Balok pr for User docs (#7139)
BeryJu
approved these changes
Oct 16, 2023
* main: (23 commits) ci: test with postgres 16 translate: Updates for file web/xliff/en.xlf in fr (#7189) web: bump the esbuild group in /web with 2 updates (#7195) web: bump the eslint group in /tests/wdio with 2 updates (#7192) core: bump ruff from 0.0.292 to 0.1.0 (#7194) web: bump the eslint group in /web with 2 updates (#7193) web: the return of pseudolocalization (#7190) rbac: revisions (#7188) website: bump @babel/traverse from 7.21.4 to 7.23.2 in /website (#7187) web: bump API Client version (#7186) core: Initial RBAC (#6806) lifecycle: re-fix system migrations (#7185) outposts: use channel groups instead of saving channel names (#7183) sources/ldap: made ldap_sync_single calls from ldap_sync_all asynchronous (#6862) website/docs: fix API OAuth token usage (#7159) web: bump rollup from 4.1.3 to 4.1.4 in /web (#7181) web: bump @formatjs/intl-listformat from 7.4.2 to 7.5.0 in /web (#7182) web: bump @rollup/plugin-replace from 5.0.3 to 5.0.4 in /web (#7177) web: bump the sentry group in /web with 2 updates (#7175) web: bump @rollup/plugin-commonjs from 25.0.5 to 25.0.7 in /web (#7178) ...
The "ApplicationWizardHint" now correctly uses the localstorage and allows the user to navigate back and see the message after it's been hidden, so that it will always be available during the test phase. The ApplicationList's old "Create Application Form" button has been restored for the purposes of the test phase. The ApplicationWizard is now available on both the ApplicationList and ProviderList pages. Tana and I discussed the microcopy, putting a stronger second-person "You can do..." twist onto the language, to give the user the sense of empowerment. The ShowHintController now has both "hide" and "show" operations, to support the hint restoration.
…mple wizard" is configured in source code and tested with storybook.
Anyway, this was a very stupid bug, because by definition function definition arguments don't have uses, they're being defined, not implemented. Fixed, conf fixed to compensate, and consequences conquered.
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
…2-with-api-and-tests' into application-wizard-2-with-api-and-tests * refs/remotes/origin/application-wizard-2-with-api-and-tests: move context from labs to main
* main: enterprise: bump license usage task frequency (#7215) web: bump the storybook group in /web with 5 updates (#7212) web: bump the sentry group in /web with 2 updates (#7211) Revert "web: Updates to the Context and Tasks libraries from lit. (#7168)" web: bump @types/codemirror from 5.60.10 to 5.60.11 in /web (#7209) web: bump @types/chart.js from 2.9.38 to 2.9.39 in /web (#7206) web: bump pyright from 1.1.331 to 1.1.332 in /web (#7208) web: bump @types/grecaptcha from 3.0.5 to 3.0.6 in /web (#7207)
This reverts commit 3718ee6.
I was very unhappy with the "update this dot-path" mechanism I was using earlier; it was hard for me to read and understand what was happening, and I wrote the darned thing. I decided instead to go with a hard substitution model; each phase of the wizard is responsible for updating the *entire* payload, mostly by creating a new payload and substituting the field value associated with the event. On the receiver, we have to do that *again* to handle the swapping of providers when the user chooses one and then another. It looks clunky, and it is, but it's *legible*; a junior dev could understand what it's doing, and that's the goal.
This reverts commit 09fedca.
…2-with-api-and-tests' into application-wizard-2-with-api-and-tests * refs/remotes/origin/application-wizard-2-with-api-and-tests: Revert "move context from labs to main"
kensternberg-authentik
added a commit
that referenced
this pull request
Oct 19, 2023
* main: (57 commits) stages/email: Fix query parameters getting lost in Email links (#5376) core/rbac: fix missing field when removing perm, add delete from object page (#7226) website/integrations: grafana: add Helm and Terraform config examples (#7121) web: bump @types/codemirror from 5.60.11 to 5.60.12 in /web (#7223) translate: Updates for file web/xliff/en.xlf in zh_CN (#7224) translate: Updates for file web/xliff/en.xlf in zh-Hans (#7225) website/blogs: blog about sso tax (#7202) web: Application wizard v2 with tests (#7004) web: bump API Client version (#7220) core: bump goauthentik.io/api/v3 from 3.2023083.7 to 3.2023083.8 (#7221) providers/radius: TOTP MFA support (#7217) web: bump API Client version (#7218) stage/deny: add custom message (#7144) docs: update full-dev-setup docs (#7205) enterprise: bump license usage task frequency (#7215) web: bump the storybook group in /web with 5 updates (#7212) web: bump the sentry group in /web with 2 updates (#7211) Revert "web: Updates to the Context and Tasks libraries from lit. (#7168)" web: bump @types/codemirror from 5.60.10 to 5.60.11 in /web (#7209) web: bump @types/chart.js from 2.9.38 to 2.9.39 in /web (#7206) ...
kensternberg-authentik
added a commit
that referenced
this pull request
Oct 19, 2023
* main: (119 commits) stages/email: Fix query parameters getting lost in Email links (#5376) core/rbac: fix missing field when removing perm, add delete from object page (#7226) website/integrations: grafana: add Helm and Terraform config examples (#7121) web: bump @types/codemirror from 5.60.11 to 5.60.12 in /web (#7223) translate: Updates for file web/xliff/en.xlf in zh_CN (#7224) translate: Updates for file web/xliff/en.xlf in zh-Hans (#7225) website/blogs: blog about sso tax (#7202) web: Application wizard v2 with tests (#7004) web: bump API Client version (#7220) core: bump goauthentik.io/api/v3 from 3.2023083.7 to 3.2023083.8 (#7221) providers/radius: TOTP MFA support (#7217) web: bump API Client version (#7218) stage/deny: add custom message (#7144) docs: update full-dev-setup docs (#7205) enterprise: bump license usage task frequency (#7215) web: bump the storybook group in /web with 5 updates (#7212) web: bump the sentry group in /web with 2 updates (#7211) Revert "web: Updates to the Context and Tasks libraries from lit. (#7168)" web: bump @types/codemirror from 5.60.10 to 5.60.11 in /web (#7209) web: bump @types/chart.js from 2.9.38 to 2.9.39 in /web (#7206) ...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
web: application wizard
Details
This commit incorporates the actual application wizard into the Web UI.
It consists of three parts:
The Wizard!
The Wizard component, which provides a framework for the Header, Nav/Breadcrumb bar, and Button Bar. That, in turn consists of four interacting components:
ak-wizard-frame
, which is a purely passive Lit component that renders the Header, Navbar, Button Bar, and central content according to properties passed into it.AKWizard
), from which all wizards inherit, and which maintains the frame and long-duration metadata associated with wizarding.The Application Wizard
The Application Wizard, which inherits from AKWizard and implements the business logic for gathering the data sent to it by its steps and deciding whether to permit forward navigation. It also provides a context for the information gathered by the Wizard. The context allows the Steps to self-render without requiring internal prop-drilling to get it there.
The BasePanel, which provides the ContextConsumer and a customized event dispatcher, further reducing the burden on each Step for how much code needs to be written for the step to be coherent.
Aside from that, the additions are the steps for the Application, the Provider, the various subtypes of providers (LDAP, OAuth, Radius, SAML, SCIM, Proxy), and the commit phase. The forms here are generally short: mostly just the renderer, with a rare custom event handler for some special cases, and a just as rare constructor for pulling down enumerated lists from the server during construction.
Tests
I’ve also provided a series of “simple,” “happy path” e2e tests that log in to the server, find the wizard, and run each of the different application types through a very basic set of paces. The good news is that the
form
objects for each provider type are independent and can be mixed into any testing system, so these form objects can be used to test the old Providers wizard just as readily, and the previous commit illustrated that.Checklist
ak test authentik/
)make lint-fix
)If an API change has been made
make gen-build
)If changes to the frontend have been made
make web
)make i18n-extract
)If applicable
make website
)