Skip to content

Commit

Permalink
Merge pull request rancher#11266 from codyrancher/final-countdown
Browse files Browse the repository at this point in the history
Remove the remaining bits of the authenticated middleware
  • Loading branch information
codyrancher authored Jul 26, 2024
2 parents 0b5cf09 + fdf7018 commit 380ece8
Show file tree
Hide file tree
Showing 13 changed files with 75 additions and 96 deletions.
1 change: 0 additions & 1 deletion shell/components/templates/blank.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import Inactivity from '@shell/components/Inactivity';
export default {
components: { Inactivity },
middleware: ['authenticated'],
mixins: [Brand],
};
</script>
Expand Down
4 changes: 0 additions & 4 deletions shell/components/templates/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ export default {
},
// Note - These will run on route change
middleware: [
'authenticated'
],
computed: {
...mapState(['managementReady', 'clusterReady']),
...mapGetters(['clusterId', 'currentProduct', 'rootProduct', 'isRancherInHarvester', 'showTopLevelMenu']),
Expand Down
2 changes: 0 additions & 2 deletions shell/components/templates/home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ export default {
mixins: [Brand, BrowserTabVisibility],
middleware: ['authenticated'],
data() {
return {
// Assume home pages have routes where the name is the key to use for string lookup
Expand Down
2 changes: 0 additions & 2 deletions shell/components/templates/plain.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ export default {
Inactivity
},
middleware: ['authenticated'],
mixins: [Brand, BrowserTabVisibility],
data() {
Expand Down
6 changes: 0 additions & 6 deletions shell/config/middleware.js

This file was deleted.

1 change: 1 addition & 0 deletions shell/config/router/navigation-guards/authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export async function authenticate(to, from, next, { store }) {
}
}

// GC should be notified of route change before any find/get request is made that might be used for that page
store.dispatch('gcStartIntervals');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,78 +1,40 @@
import { DEFAULT_WORKSPACE } from '@shell/config/types';
import { applyProducts } from '@shell/store/type-map';
import { ClusterNotFoundError, RedirectToError } from '@shell/utils/error';
import { get } from '@shell/utils/object';
import { AFTER_LOGIN_ROUTE, WORKSPACE } from '@shell/store/prefs';
import { BACK_TO } from '@shell/config/local-storage';
import { NAME as FLEET_NAME } from '@shell/config/product/fleet.js';
import { validateResource, setProduct } from '@shell/utils/auth';
import { getClusterFromRoute, getProductFromRoute, getPackageFromRoute } from '@shell/utils/router';
import { getClusterFromRoute, getProductFromRoute, getPackageFromRoute, routeRequiresAuthentication } from '@shell/utils/router';

let beforeEachSetup = false;

export default async function({
route, store, redirect, from, $plugin, next
}) {
if ( store.getters['auth/enabled'] !== false && !store.getters['auth/loggedIn'] ) {
return;
}

const backTo = window.localStorage.getItem(BACK_TO);

if (backTo) {
window.localStorage.removeItem(BACK_TO);

window.location.href = backTo;
}

// GC should be notified of route change before any find/get request is made that might be used for that page
store.dispatch('gcRouteChanged', route);

// Load stuff
let localCheckResource = false;

await applyProducts(store, $plugin);

// Setup a beforeEach hook once to keep track of the current product
if ( !beforeEachSetup ) {
beforeEachSetup = true;
// This only needs to happen when beforeEach hook hasn't run (the initial load)
localCheckResource = true;

store.app.router.beforeEach((to, from, next) => {
// NOTE - This beforeEach runs AFTER this middleware. So anything in this middleware that requires it must set it manually
setProduct(store, to);

next();
});

// Call it for the initial pageload
setProduct(store, route);
export function install(router, context) {
router.beforeEach((to, from, next) => loadClusters(to, from, next, context));
}

store.app.router.afterEach((to, from) => {
// Clear state used to record if back button was used for navigation
setTimeout(() => {
window._popStateDetected = false;
}, 1);
});
export async function loadClusters(to, from, next, { store }) {
if (!routeRequiresAuthentication(to)) {
return next();
}

try {
let clusterId = get(route, 'params.cluster');
let clusterId = get(to, 'params.cluster');

// Route can provide cluster ID via metadata
if (!clusterId && route) {
clusterId = getClusterFromRoute(route);
if (!clusterId && to) {
clusterId = getClusterFromRoute(to);
}

const pkg = getPackageFromRoute(route);
const product = getProductFromRoute(route);
const pkg = getPackageFromRoute(to);
const product = getProductFromRoute(to);

const oldPkg = getPackageFromRoute(from);
const oldProduct = getProductFromRoute(from);

// TODO: Replace all references to store.$plugin.
// Unfortunately the initialization code has circular dependencies between creating
// the router and creating the store that will need to be untangled before this can be tackled.

// Leave an old pkg where we weren't before?
const oldPkgPlugin = oldPkg ? Object.values($plugin.getPlugins()).find((p) => p.name === oldPkg) : null;
const oldPkgPlugin = oldPkg ? Object.values(store.$plugin.getPlugins()).find((p) => p.name === oldPkg) : null;

if (oldPkg && oldPkg !== pkg ) {
// Execute anything optional the plugin wants to. For example resetting it's store to remove data
Expand All @@ -90,10 +52,10 @@ export default async function({
];

// Entering a new package where we weren't before?
const newPkgPlugin = pkg ? Object.values($plugin.getPlugins()).find((p) => p.name === pkg) : null;
const newPkgPlugin = pkg ? Object.values(store.$plugin.getPlugins()).find((p) => p.name === pkg) : null;

// Note - We can't block on oldPkg !== newPkg because on a fresh load the `from` route equals the `to` route
if (pkg && (oldPkg !== pkg || from.fullPath === route.fullPath)) {
if (pkg && (oldPkg !== pkg || from.fullPath === to.fullPath)) {
// Execute mandatory store actions
await Promise.all(always);

Expand All @@ -110,7 +72,7 @@ export default async function({
// When fleet moves to it's own package this should be moved to pkg onEnter/onLeave
if ((oldProduct === FLEET_NAME || product === FLEET_NAME) && oldProduct !== product) {
// See note above for store.app.router.beforeEach, need to setProduct manually, for the moment do this in a targeted way
setProduct(store, route);
setProduct(store, to);

store.commit('updateWorkspace', {
value: store.getters['prefs/get'](WORKSPACE) || DEFAULT_WORKSPACE,
Expand All @@ -128,13 +90,11 @@ export default async function({
newPkg: newPkgPlugin,
product,
oldProduct,
targetRoute: route
targetRoute: to
})
]);

if (localCheckResource) {
validateResource(store, route, redirect);
}
validateResource(store, to);

if (!clusterId) {
clusterId = store.getters['defaultClusterId']; // This needs the cluster list, so no parallel
Expand All @@ -156,16 +116,17 @@ export default async function({
});
}
}
next();
} catch (e) {
if ( e.name === ClusterNotFoundError.name ) {
return redirect(302, '/home');
return next('/home');
} if ( e.name === RedirectToError.name ) {
return redirect(302, e.url);
return next(e.url);
} else {
// Sets error 500 if lost connection to API
store.commit('setError', { error: e, locationError: new Error(store.getters['i18n/t']('nav.failWhale.authMiddleware')) });

return redirect(302, '/fail-whale');
return next('/fail-whale');
}
}
}
13 changes: 13 additions & 0 deletions shell/config/router/navigation-guards/history.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function install(router, context) {
router.beforeEach((to, from, next) => loadHistory(to, from, next, context));
}

export async function loadHistory(to, from, next) {
// Clear state used to record if back button was used for navigation
// TODO: Investigate if this can be removed. This is only used on the templates/error.vue page and seems hacky.
setTimeout(() => {
window._popStateDetected = false;
}, 1);

next();
}
5 changes: 4 additions & 1 deletion shell/config/router/navigation-guards/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { install as installAttemptFirstLogin } from '@shell/config/router/naviga
import { install as installAuthentication } from '@shell/config/router/navigation-guards/authentication';
import { install as installRuntimeExtensionRoute } from '@shell/config/router/navigation-guards/runtime-extension-route';
import { install as installI18N } from '@shell/config/router/navigation-guards/i18n';
import { install as installProducts } from '@shell/config/router/navigation-guards/products';
import { install as installHistory } from '@shell/config/router/navigation-guards/history';
import { install as installClusters } from '@shell/config/router/navigation-guards/clusters';

/**
* Install our router navigation guards. i.e. router.beforeEach(), router.afterEach()
Expand All @@ -11,7 +14,7 @@ export function installNavigationGuards(router, context) {
// NOTE: the order of the installation matters.
// Be intentional when adding, removing or modifying the guards that are installed.

const navigationGuardInstallers = [installLoadInitialSettings, installAttemptFirstLogin, installAuthentication, installRuntimeExtensionRoute, installI18N];
const navigationGuardInstallers = [installLoadInitialSettings, installAttemptFirstLogin, installAuthentication, installProducts, installHistory, installClusters, installRuntimeExtensionRoute, installI18N];

navigationGuardInstallers.forEach((installer) => installer(router, context));
}
15 changes: 15 additions & 0 deletions shell/config/router/navigation-guards/products.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { setProduct } from '@shell/utils/auth';
import { applyProducts } from '@shell/store/type-map';

export function install(router, context) {
router.beforeEach((to, from, next) => loadProducts(to, from, next, context));
}

export async function loadProducts(to, from, next, { store }) {
// GC should be notified of route change before any find/get request is made that might be used for that page
store.dispatch('gcRouteChanged', to);

await applyProducts(store, store.$plugin);
setProduct(store, to);
next();
}
22 changes: 10 additions & 12 deletions shell/initialize/entry-helpers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Vue from 'vue';
import { updatePageTitle } from '@shell/utils/title';
import { getVendor } from '@shell/config/private-label';
import middleware from '@shell/config/middleware.js';
import { withQuery } from 'ufo';

// Global variable used on mount, updated on route change and used in the render function
Expand Down Expand Up @@ -122,30 +121,29 @@ export const middlewareSeries = (promises, appContext) => {
*/
function callMiddleware(Components, context) {
let midd = [];
let unknownMiddleware = false;

Components.forEach((Component) => {
if (Component.options.middleware) {
midd = midd.concat(Component.options.middleware);
}
});

midd = midd.filter((middleware) => {
const isMiddlwareFunction = typeof middleware === 'function';

if (!isMiddlwareFunction) {
console.warn('All middleware is deprecated. For a short time inline middleware specified as a function will continue to work.', `We noticed '${ middleware }' middleware is still being used.`); // eslint-disable-line no-console
}

return isMiddlwareFunction;
});

midd = midd.map((name) => {
if (typeof name === 'function') {
return name;
}
if (typeof middleware[name] !== 'function') {
unknownMiddleware = true;
errorRedirect(this, new Error(`500: Unknown middleware ${ name }`));
}

return middleware[name];
});

if (unknownMiddleware) {
return;
}

return middlewareSeries(midd, context);
}

Expand Down
5 changes: 5 additions & 0 deletions shell/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,11 @@ export const mutations = {
},

setError(state, { error: obj, locationError }) {
// We don't want to clobber one error with another, doing so can hide the original cause of an error
if (obj && state.error) {
return;
}

const err = new ApiError(obj);

console.log('Loading error', err); // eslint-disable-line no-console
Expand Down
4 changes: 1 addition & 3 deletions shell/utils/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,7 @@ export function setProduct(store, to) {
(product && !store.getters['type-map/isProductRegistered'](product))) {
const error = new Error(store.getters['i18n/t']('nav.failWhale.productNotFound', { productNotFound: product }, true));

store.dispatch('loadingError', error);

throw new Error('loadingError', new Error(store.getters['i18n/t']('nav.failWhale.productNotFound', { productNotFound: product }, true)));
return store.dispatch('loadingError', error);
}

if ( !product ) {
Expand Down

0 comments on commit 380ece8

Please sign in to comment.