Web: always set redux auth and wait for it

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
This commit is contained in:
James E. Blair 2022-09-27 15:38:22 -07:00
parent 25c948d2a0
commit 90d8d8fc4b
2 changed files with 26 additions and 13 deletions

View File

@ -117,7 +117,7 @@ class App extends React.Component {
}
renderContent = () => {
const { info, tenant } = this.props
const { info, tenant, auth } = this.props
const allRoutes = []
if ((window.location.origin + window.location.pathname) ===
@ -126,7 +126,7 @@ class App extends React.Component {
// validation is complete (it will internally redirect when complete)
return <AuthCallbackPage/>
}
if (info.isFetching) {
if (info.isFetching || !auth.info || auth.isFetching) {
return <Fetching />
}
this.menu
@ -189,14 +189,14 @@ class App extends React.Component {
this.props.dispatch(tenantAction)
if (tenantName) {
this.props.dispatch(fetchConfigErrorsAction(tenantAction.tenant))
if (whiteLabel) {
// The app info endpoint was already a tenant info
// endpoint, so auth info was already provided.
this.props.dispatch(configureAuthFromInfo(info))
} else {
// Query the tenant info endpoint for auth info.
this.props.dispatch(configureAuthFromTenant(tenantName))
}
}
if (whiteLabel || !tenantName) {
// The app info endpoint was already a tenant info
// endpoint, so auth info was already provided.
this.props.dispatch(configureAuthFromInfo(info))
} else {
// Query the tenant info endpoint for auth info.
this.props.dispatch(configureAuthFromTenant(tenantName))
}
}
}

View File

@ -56,8 +56,14 @@ it('renders multi tenant', async () => {
const auth_election = createLeaderElection(channel)
api.fetchInfo.mockImplementation(
() => Promise.resolve({data: {
info: {capabilities: {}}
}})
info: {
capabilities: {
auth: {
realms: {},
default_realm: null,
},
},
}}})
)
api.fetchTenants.mockImplementation(
() => Promise.resolve({data: [{name: 'openstack'}]})
@ -100,7 +106,14 @@ it('renders single tenant', async () => {
const auth_election = createLeaderElection(channel)
api.fetchInfo.mockImplementation(
() => Promise.resolve({data: {
info: {capabilities: {}, tenant: 'openstack'}
info: {
capabilities: {
auth: {
realms: {},
default_realm: null,
},
},
tenant: 'openstack'}
}})
)
api.fetchStatus.mockImplementation(