We currently fetch all of the config errors in order to decide whether or
not to show the bell icon in the web ui (which indicates that there are
errors). We recently added a tenant-status endpoint which returns a simple
error count instead of the entire data structure. Use that to decide
whether to show the bell instead.
This builds on the previous change that fetches the config errors on-demand
rather than storing them in the redux store. With that change and this
combined, we no longer need to store the errors in redux. Instead we will
store the error count in redux so we only have to fetch it once when
switching tenants.
Change-Id: I3dfd911af9ba55dd55ca3649ee5ecf6edaa3581a
This switches the config error page to use the new server-side
filtering and pagination support. Note that we still fetch the
full set of config errors in order to display the bell icon. That
will be updated in a future change.
Change-Id: I08a554c2a8151e24e5423608ef016f3273b3d663
When making a websocket request, browsers do not send the
"Authorization" header. Therefore if a Zuul tenant is run in
a configuration where authz is required for read-only access,
the websocket-based log streaming will always fail.
To correct this, we will remove the http request authz check
from the console-stream endpoint, and add an optional token
parameter to the websocket message payload. The JS web app
will be responsible for sending the auth token in the payload,
and the web server will validate it if it is required for the
tenant. Thanks to Andrei Dmitriev for this suggestion.
Since we essentially have two different authz code paths in
zuul-web now, in order to share as much code as possible, the
authz sequence is refactored in such a way that the final authz
check can be deferred. First we create an AuthContext at the
start of the request which stores tenant and header information,
then the actual validation is performed in a separate step where
the token can optionally be provided.
In the http code path, we create the AuthContext and validate
immediately, using the Authorization header, and we do all of that
in the cherrypy tool at the start of the request.
In the websocket code path, we create the AuthContext as the
websocket handler is being created by the cherrypy request handler,
then we perform validation after receiving a message on the
websocket. We use the token supplied from the request.
Error handling is adjusted so in the http code path, exceptions
that return appropriate http errors are raised, but in the
websocket path, these are caught and translated into websocket
close calls.
A related issue is that we perform no validation that the
streaming build log being requested belongs to the tenant via
which the request is being sent. This was unecessary before
read-only access was an option, but now that it is, we should
check that a streaming build request arrives via the correct
tenant URL. This change adjusts that as well.
During testing, it was noted that the tenant configuration syntax
allows admin-rules and access-rules to use the scalar-or-list
pattern, however some parts of the code assumed only lists. The
configloader is updated to use scalar-or-list for both of those
values.
Change-Id: Ifd4c21bb1fe962bf23acb5b4f10b3bbaba61e63a
Co-Authored-By: Andrei Dmitriev <andrei.dmitriev@nokia.com>
We discovered that the build process strips trailing slashes
from PUBLIC_URL, which thwarted our plans in getHomepageUrl.
This ensures the function always returns a trailing slash.
Change-Id: I03c4ec79ee4566a8b7fbd4e04c18e86f4257fa8f
The getHomepageUrl function searches for /# when trying to find hash
anchors in the URL. This misses URLs that don't end with a trailing slash
(i.e http://localhost:3000/auth_callback#state=231231231)
To fix this, this commit switches to using the built-in URL data type
which handles this case and all the other cases.
Change-Id: I15827f4cb4c28f3163a4b4e84b872331b972b156
Signed-off-by: Flavio Percoco <flavio@pacerevenue.com>
Co-Authored-By: Radosław Piliszek <radoslaw.piliszek@gmail.com>
This updates the web UI to support the requirement for authn/z
for read-only access.
If authz is required for read access, we will automatically redirect.
If we return and still aren't authorized, we will display an
"Authorization required" page (rather than continuing and popping up
API error notifications).
The API methods are updated to send an authorization token whenever
one is present.
Change-Id: I31c13c943d05819b4122fcbcf2eaf41515c5b1d9
If the Zuul web UI is placed behind an authorizing proxy system,
such as Apache mod_auth_mellon for SAML, then when the service
provider token times out, users will not receive any indication
that has occurred. If they are watching the status page, it will
just silently fail to update. Switching to another page may bring
it to their attention, unless we already have cached data, in which
case there still may be no indication.
In these cases, the authorizy proxy sends a redirect (HTTP 303)
instead of the normal response, but since our requests are async
background requests from JS, they are subject to CORS rules and
because they arrive without an Access-Control-Allow-Origin header,
the response is unavailable to us. (Even if they do arrive with
that header (say by the use of apache mod_headers with "always set"),
the ultimate target of the redirect also needs to have that header,
which is very unlikely in the case of an ID provider.)
Even though we have no information about the response due to the
CORS restrictions, we can detect this situation, at least with
mod_auth_mellon, and possibly others, by adding the X-Requested-With
header. This can be used to indicate that the request is from JS
instead of the user, and in this case, mod_auth_mellon returns a
403 instead of a 303. We do have access to the 403 response (unlike
the 303) so we can detect this case.
In other words after receiving an undefined response (which could be
DNS, network, or CORS error), we can narrow that down by repeating
the request with the X-Requested-With header, and if we then get
a 403, we can be fairly certain the first error was CORS and that we
need to re-authenticate. We still don't have access to the redirect
target that the auth proxy wants us to use, so the best we can do
is to just reload the page and let the auth proxy perform a redirect
based on the normal user request that this appears as.
Why not always include X-Requested-With? That's because without that
header, the browser considers most of our GET requests to be "simple"
which means that they do not require pre-flight checks (where the
browser performs an OPTIONS request before executing the actual GET).
Adding that header to every GET would double the number of HTTP
requests in normal operation (even for sites without auth proxies),
so it is worth our while to keep our simple GET requests simple.
Change-Id: I7c82110d033550c451d21306de94f223a5fcceb2
This updates the OpenAPI docs to include the semaphores endpoint,
and adds a Semaphores tab to the web UI to show information about
semaphores within a tenant.
Change-Id: If78b27131ac76aff93c47a986fce6eae3e068668
This adds a freeze-job page to the web UI. It can be navigated to
by clicking a job in a job graph.
Change-Id: Ibd07449314a9454295bc97f8d654347f09dc504c
This adds the ability to display the frozen job graph for a project.
It adds a toolbar to the Project page that allows a user to enter
a pipeline and branch. Hit the button and it will use the API
to freeze the job graph and then display it with graphviz (there
is a webassembly build of the graphviz libray).
Change-Id: Ieb5899a63a4c85eb5d445fa69dd1e85ddc11575d
Add a "promote" button in the actions menu of a change, if the
currently logged in user is an admin on the tenant and if the pipeline
is dependent.
Clicking the button opens a modal, so that the user can confirm her decision.
Change-Id: I8262888aef9ba1a106e0b321cc4cf2e14465b90c
A user can list active autoholds for a given tenant. If the user is a
tenant admin, she can also discard a autohold request from the autoholds
page.
Add a autohold page holding information about a single autohold request,
in particular links to held builds if any.
Change-Id: I4f5f2cfdf8e46ce8fb7ac69e330d6e51bd8b19fe
Add a "autohold" command on a build page, displayed only if the currently
logged in user is an admin on the tenant. By clicking the command, the
user can display a form and set custom parameters for an autohold
request.
Change-Id: I0f9f069d4ad36d4961eb6925146f67fe4910cb2e
Add a "re-enqueue" action command on a Buildset page, displayed only
if the currently logged in user is an admin on the tenant. By
clicking this command, the user can re-enqueue the change with
the same parameters as the buildset.
Redux: turned the API error notifications into a more generic
notification system, that can now include success notifications.
Change-Id: I05b6b3deb912b121df8de207944d9ec26e7c92d1
Add a togglable "Actions" kebab menu on the right of a change, if the
currently logged in user is an admin on the tenant.
Show available actions (currently "dequeue" only) when toggled.
Clicking the "Dequeue" item opens a modal, so that the user
can confirm her decision.
Change-Id: I7c97509d62ef167ee5904a816998049d88c6b3cb
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 implements the necessay async functions to retrieve the components
from the new /components API endpoint.
Change-Id: I709467f4a23b0082e8362e69aaa84421a7ac7c36
Previously indentation was not checked at all and in order to avoid
reviewers time with style checks, we can enforce it with eslint.
Current js/jsx changes were made by: yarn lint-fix
Note this this change can easily become outdated so we need to
coordinate and merge it quickly as each rebase would loose previous
votes.
Change-Id: I85883fc8db924ad4ce9acad5acdd42aed7e4d0e4
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
This change adds a swagger description of the REST API. The description is
rendered in the sphinx user documentations and in the web interface.
Change-Id: I753524f40a09874dab5952f14ab17025525bbab9
This changes adds a new dashboard page to display nodes status.
Depends-On: https://review.openstack.org/553998
Change-Id: If17ddc2788e8e62f9860c405ad401b04bdf4502b
This changes adds a new dashboard page to display available labels.
Depends-On: https://review.openstack.org/553979
Change-Id: I1d028fc1bea80cca37811ced72ceaa5100b558ea
This change adds a ChangeStatus page to display the status of a single
change and updates the Change component to link the icon to the new
page.
Change-Id: I265f7a390fde33721624a0da7fe5bd1cde32dc37
This change adds a Notification drawer to display the config errors and
a dedicated config-errors web interface.
Change-Id: I5cfc608219e26848a20f14e6c99bdb166ac67121
This change adds a /build/{build_uuid} web interface.
Depends-On: https://review.openstack.org/592225
Change-Id: I4c4b3dc028b7be9f11e959bfca37867eafa9ca3f
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