On a non whitelabeled setup, allow a user to jump from one tenant to
another without having to go back to the tenants page.
On a whitelabeled setup, make the tenant item non-clickable (the click
doesn't do anything anyway).
Change-Id: I94d27445c65ed5c3f8d02fae9d47d426528d2332
Currently we only set the auth redux property within the tenant
scope. But we're going to extend authentication to outside the
tenant scope (to optionally restrict access to the tenant list).
To accommodate that, we will always update the auth property in
redux any time our tenant changes (including when it changes to
undefined), and we will wait until we have finished auth configuration
before rendering any pages in the app.
This is effectively a no-op change from the end-user point of view,
except that we may wait just a bit longer (for the /api/tenant/info
endpoint to return) before showing an initial page for a tenant.
Change-Id: I18e74fa205f75a7b020bf23c8652226e5170d88b
There is no /api/tenant/$tenant/components URL, so hide the
"Components" link in the page header when the web ui is accessing
a whitelabel tenant.
Change-Id: I707bf03489016264ce6a37b4eb005e9680de90a2
This was suggested and written by Joachim Schuler in [1]. It moves
the top navbar as a "tertiary" option to the page header. This bar is
always visible and doesn't roll-up into the "top" area. This means we
can drop the more complex grid layout that is trying to keep this bar
always visible for some much more simple styling.
As this moves the navbar location the link matching is updated to find
new elements.
[1] https://github.com/patternfly/patternfly-react/issues/7960#issuecomment-1244017295
Change-Id: I4a61a1e246ca4fe0d96f630a06be7f0264782723
By default the UserManager uses session storage for its authentication
credentials. That is restricted to a single tab. In order to support
using the same auth token in multiple tabs, we could switch that to
localStorage which is shared by all tabs of the same domain. But then
if a user exited the browser, they might be surprised to find that they
were still logged in when restarting. The typically short lifetime of
OIDC tokens mitigates that somewhat, but it's probably best not to
subvert that expectation anyway.
Instead, we can continue to use session storage by using a BroadcastChannel
to notify other tabs of login/out events and transfer the token info as
well. This is a standard feature of modern browsers, but we're using
a library that wraps it for two reasons: it supports older browsers
with compatability workarounds if required, and it implements a leader
election protocol. More on that in a minute.
We would also like to automatically renew tokens shortly before they
expire. The UserManager has an automatic facility for that, but it
isn't multi-tab aware, so every tab would try to renew at the same time
if we used it. Instead, we hook into the UserManager timer that fires
about one minute before token expiration and use the leader election to
decide which tab will renew the token.
We renew the token silently in the background with a hidden iframe. In
this case, instead of using our normal auth callback page, we use a much
simpler "silent callback" which does not render the rest of our application.
This avoids confusion and reduces resource usage.
This also moves any remaining token lifecycle handling out of the Auth
component and into ZuulAuthProvider, so the division of responsibilities
is much simpler.
Change-Id: I17af1a98bf8d704dd7650109aa4979b34086e2fa
Under the hood, this uses AuthProvider as supplied by oidc-react.
Most of the theory is explained in the comment in ZuulAuthProvider.jsx
The benefit of doing this is that we allow the AuthProvider and
userManager to handle the callback logic, so we don't need to
handle the callback logic ourselves. A callback page is still required
though in order to deal with the parameters passed in a successful
redirection from the Identity Provider.
The challenge in using these classes as-is is that our authority
endpoints (eg, the IDP itself) may change from one tenant to
the next; these classes aren't set up for that. So we need to be
careful about how and when we change those authority URLs.
In terms of functionalities: if the default realm's authentication driver
is set to "OpenIDConnect", display a "Sign in" button. If the the user
is logged in, redirect to the last page visited prior to logging in;
fetch user authorizations and add them to the redux store; display the
user's preferred username in the upper right corner. Clicking on the
user icon in the right corner displays a modal with user information
such as the user's zuul-client configuration, and a sign out button.
Clicking on the sign out button removes user information from the
store (note that it does not log the user out from the Identity Provider).
Add some basic documentation explaining how to configure Zuul with
Google's authentication, and with a Keycloak server.
(This squashes https://review.opendev.org/c/zuul/zuul/+/816208 into
https://review.opendev.org/c/zuul/zuul/+/734082 )
Co-authored-by: James E. Blair <jim@acmegating.com>
Change-Id: I31e71f2795f3f7c4253d0d5b8ed309bfd7d4f98e
This updates react-router-dom to not quite the latest version, but
a new enough version that it supports hooks.
This also changes how React Refs are handled in such a way that
it breaks some tests which rely on on reaching through the redux
store into child nodes. To resolve this, some tests are updated
to use the react-test-renderer instead.
The tests in App.test.jsx were not asserting anything past the
initial toEqual assertion in the path, which is why they are only
now being updated to match links added since the test inception.
Change-Id: Ia80fbfe3cf2d2d275fd8422111ec193c467bf606
This enables the redux developer tools for the browser. To make use of
this, one must also install the Redux DevTools extension which is
available for various browsers. The extension visualize all state
transitions in the redux store and also allows changing them manually to
see the effects.
Additionally, this change makes use of the third-party library called
"redux-immutable-state-invariant", which throws exception in development
mode whenever a state is mutated directly within an action or reducer.
Change-Id: I8a8588cd7f5f1b17b247d9700a492e5c1e27f040
While trying to figure out why the ansi patch wouldn't
build it emerged that we're now 2 major releases behind
on create-react-app.
Update create-react-app to the latest 3.4.1. This also updates
react to 16.13, and updates eslint globals processing so that
we don't have to declare globals in headers when we've
declared them already in the eslint file.
Finally, although this doesn't do it, create-react-app 3
has support for typescript, so if we want we can start migrating
files to .ts or .tsx extensions and start doing typing in
them.
Pin nanoid to v2 until such a time as create-react-app can be
updated to 3.4.2 which is needed ot handle .cjs extensions
being used by nanoid.
Change-Id: Ibc69bef605a62e4fdd2ebba33d9d1b822e7dfeba
ES6 modules are evaluated only once on first import. They behave like singleton.
Some redux librairies except the store to be a singleton.
Returning a function and invoking it remove this behavior.
Change-Id: I74ff516567d4b7bcf5f1e2d3004eb4617817f117
This change adds info fetch state action type and simplifies the main App
by using the new info attributes.
Change-Id: I2cfd3f6ae605051e11f58272e62925d8f97e4ac9
This change applies best practices to split the current reducers module
in logical unit. Each reducer and its actions are moved into different
modules to ease further refactor and follow-up tests.
Change-Id: I75cc41ca3d31a61046868aafbc84505de661a99d
This change adds a Notification drawer to display the config errors and
a dedicated config-errors web interface.
Change-Id: I5cfc608219e26848a20f14e6c99bdb166ac67121
Revert "Fix publish-openstack-javascript-content"
This reverts commit ca199eb9db.
This reverts commit 1082faae95.
This appears to remove the tarball publishing system that we rely on.
Change-Id: Id746fb826dfc01b157c5b772adc1d2991ddcd93a