* web/wdio-2:
remove hooks
add basic CI
prettier run
add dependabot
update package name
fix blueprints
web: improve testing by adding test admin user via blueprint
This commit continues the application wizard buildout. In this commit are the following changes:
- Fixed a width-setting bug in the Makefile `make help` feature (i.e "automate that stuff!")
- Added Radius to the list of providers we can offer via the wizard
- Added `launchUrl` and `UI Settings` to features of the application page the wizard can find
- Changed 'SAML Manual Configuration' to just say "SAML Configuration"
- Modified `ak-form-group` to take and honor the `aria-label` property (which in turn makes it
easier to target specific forms with unit testing)
- Reduced the log level for wdio to 'warn'; 'info' was super-spammy and not helpful. It can be put
back with `--logLevel info` from the command line.
- Added SCIM to the list of available providers
- Fixed ForwardProxy so that its mode is set correctly. (This is a special case in the committer;
I'm unhappy with that.)
- Fixed the commit messages so that:
- icons are set correctly (Success, Danger, Working)
- icons are colored correctly according to state
- commit message includes a `data-commit-state` field so tests can find it!
- Merged the application wizard tests into a single test pass
- Isolated common parts of the application wizard tests to reduce unnecessary repetition. All
application tests are the same until you reach the provider section anyway.
- Fixed the unit tests so they're finding the right error messages and are enabled to display them
correctly.
- Moved the test Form handlers into their own folder so they're not cluttering up the Pages folder.
* web/wdio-2:
web/test: changed the name of one test to reflect it's 'good' status
web/adding tests: added comments and cleaned up some administrative features.
web/add webdriverIO testing layer
This commit adds WebdriverIO as an end-to-end solution to unit testing. WebdriverIO can be run both
locally and remotely, supports strong integration with web components, and is generally robust for
use in pipelines. I'll confess to working through a tutorial on how to do this for web components,
and this is just chapter 2 (I think there are 5 or so chapters...).
There's a makefile, with help! If you just run `make` it tells you:
```
Specify a command. The choices are:
help Show this help
node_modules Runs `npm install` to prepare this feature
precommit Run the precommit: spell check all comments, eslint with sonarJS, prettier-write
test-good-login Test that we can log into the server. Requires a running instance of the server.
test-bad-login Test that bad usernames and passwords create appropriate error messages
```
... because Makefiles are documentation, and documentation belongs in Makefiles.
I've chosen to go with a PageObject-oriented low-level DSL; what that means is that for each major
components (a page, a form, a wizard), there's a class that provides human-readable names for
human-interactable and human-viewable objects on the page. The LoginPage object, for example, has
selectors for the username, password, submit button, and the failure alert; accessing those allows
us to test for items as expected., and to write a DSL for "a good login" that's as straightforward
as:
```
await LoginPage.open();
await LoginPage.login("ken@goauthentik.io", "eat10bugs");
await expect(UserLibraryPage.pageHeader).toHaveText("My applications");
```
There was a *lot* of messing around with the LoginPage to get the username and password into the
system. For example, I had to do this with all the `waitForClickable` and `waitForEnable` because
we both keep the buttons inaccessible until the form has something and we "black out" the page (put
a darkening filter over it) while accessing the flow, meaning there was a race condition such that
the test would attempt to interact with the username or password field before it was accessible.
But this works now, which is very nice.
``` JavaScript
get inputUsername() {
return $('>>>input[name="uidField"]');
}
get btnSubmit() {
return $('>>>button[type="submit"]');
}
async username(username: string) {
await this.inputUsername.waitForClickable();
await this.inputUsername.setValue(username);
await this.btnSubmit.waitForEnabled();
await this.btnSubmit.click();
}
```
The bells & whistles of *Prettier*, *Eslint*, and *Codespell* have also been enabled. I do like my
guardrails.
This commit replaces the previous WDIO instance with a more formal and straightforward process using
the [pageobjects](https://martinfowler.com/bliki/PageObject.html). In this form, every major
component has its own test suite, and a test is a sequence of exercises of those components.
A test then becomes something as straightforward as:
```
await LoginPage.open();
await LoginPage.login("ken@goauthentik.io", "eat10bugs");
expect(await UserLibraryPage.pageHeader).toHaveText("My Applications");
await UserLibraryPage.goToAdmin();
expect(await AdminOverviewPage.pageHeader).toHaveText("Welcome, ");
await AdminOverviewPage.openApplicationsListPage();
expect(await ApplicationsListPage.pageHeader).toHaveText("Applications");
ApplicationsListPage.startCreateApplicationWizard();
await ApplicationWizard.app.name.setValue(`Test application ${newId}`);
await ApplicationWizard.nextButton.click();
await (await ApplicationWizard.getProviderType("ldapprovider")).click();
await ApplicationWizard.nextButton.click();
await ApplicationWizard.ldap.setBindFlow("default-authentication-flow");
await ApplicationWizard.nextButton.click();
await expect(await ApplicationWizard.commitMessage).toHaveText(
"Your application has been saved"
);
```
Whether or not there's another layer of DSL in there or not, this is a pretty nice idiom for
maintaining tests.
* main: (184 commits)
web/admin: user details few tooltip buttons (#6899)
website/blogs: added emm dashes (#6927)
core: bump goauthentik.io/api/v3 from 3.2023083.2 to 3.2023083.3 (#6925)
core: bump ruff from 0.0.289 to 0.0.290 (#6923)
web: bump the babel group in /web with 2 updates (#6919)
web: bump the storybook group in /web with 5 updates (#6920)
web: bump rollup from 3.29.1 to 3.29.2 in /web (#6921)
core: bump pycryptodome from 3.18.0 to 3.19.0 (#6922)
core: bump django-filter from 23.2 to 23.3 (#6924)
core: bump github.com/go-ldap/ldap/v3 from 3.4.5 to 3.4.6 (#6926)
web: bump API Client version (#6918)
core: create app transactional api (#6446)
sources/ldap: add warning when a property mapping returns None or bytes (#6913)
website: replace login card with png (#6911)
core: compile backend translations (#6912)
translate: Updates for file locale/en/LC_MESSAGES/django.po in zh-Hans on branch main (#6910)
translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN on branch main (#6907)
translate: Updates for file web/xliff/en.xlf in zh_CN on branch main (#6908)
translate: Updates for file web/xliff/en.xlf in zh-Hans on branch main (#6909)
web/admin: fix webauthn label order, add raw value (#6905)
...
After working with the navigation for awhile, I realized that it's a poor map; what I really wanted was
a controller/view pair, where events flow up to the controller and then messages on "what to draw" flow
down to the view. It work quite well, and the wizard frame is smaller and smarter for it.
I've also moved the WDIO-driven tests into the 'tests' folder, because it (a) makes more sense to put
them there, and (b) it prevents any confusion about who's in charge of node_modules.
* stages/email: directly use email credentials from config
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* use custom database backend that supports dynamic credentials
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix tests
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* add crude config reloader
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* make method names for CONFIG clearer
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* replace config.set with environ
Not sure if this is the cleanest way, but it persists through a config reload
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* re-add set for @patch
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* even more crudeness
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* clean up some old stuff?
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* somewhat rewrite config loader to keep track of a source of an attribute so we can refresh it
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* cleanup old things
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix flow e2e
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* don't open inspector by default when debug is enabled
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* encode error in fragment when using hybrid grant_type
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* require nonce for all response_types that get an id_token from the authorization endpoint
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* don't set empty family_name
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* only set at_hash when response has token
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* cleaner way to get login time
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* remove authentication requirement from authentication flow
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* use wrapper
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix auth_time not being handled correctly
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* minor cleanup
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* add test files
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* fix tests
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* remove USER_LOGIN_AUTHENTICATED
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* rework prompt=login handling
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
* also set last login uid for max_age check to prevent double login when max_age and prompt=login is set
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
---------
Signed-off-by: Jens Langhammer <jens@goauthentik.io>