UI/add managed ns redirect prefix (#14422)

* The UI redirects to properly prefixed namespace if some other namespace is passed instead, with tests

* Fix ordering

* Add changelog
This commit is contained in:
Chelsea Shaw 2022-03-10 08:26:33 -06:00 committed by GitHub
parent 40e24f3688
commit c6318713ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 6 deletions

3
changelog/14422.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
ui: Redirects to managed namespace if incorrect namespace in URL param
```

View File

@ -10,6 +10,16 @@ import ModelBoundaryRoute from 'vault/mixins/model-boundary-route';
const POLL_INTERVAL_MS = 10000; const POLL_INTERVAL_MS = 10000;
export const getManagedNamespace = (nsParam, root) => {
if (!nsParam || nsParam.replaceAll('/', '') === root) return root;
// Check if param starts with root and /
if (nsParam.startsWith(`${root}/`)) {
return nsParam;
}
// Otherwise prepend the given param with the root
return `${root}/${nsParam}`;
};
export default Route.extend(ModelBoundaryRoute, ClusterRoute, { export default Route.extend(ModelBoundaryRoute, ClusterRoute, {
namespaceService: service('namespace'), namespaceService: service('namespace'),
version: service(), version: service(),
@ -38,20 +48,25 @@ export default Route.extend(ModelBoundaryRoute, ClusterRoute, {
const params = this.paramsFor(this.routeName); const params = this.paramsFor(this.routeName);
let namespace = params.namespaceQueryParam; let namespace = params.namespaceQueryParam;
const currentTokenName = this.auth.get('currentTokenName'); const currentTokenName = this.auth.get('currentTokenName');
// if no namespace queryParam and user authenticated, const managedRoot = this.featureFlagService.managedNamespaceRoot;
// use user's root namespace to redirect to properly param'd url if (managedRoot && this.version.isOSS) {
if (this.featureFlagService.managedNamespaceRoot && this.version.isOSS) { // eslint-disable-next-line no-console
console.error('Cannot use Cloud Admin Namespace flag with OSS Vault'); console.error('Cannot use Cloud Admin Namespace flag with OSS Vault');
} }
if (!namespace && currentTokenName && !Ember.testing) { if (!namespace && currentTokenName && !Ember.testing) {
// if no namespace queryParam and user authenticated,
// use user's root namespace to redirect to properly param'd url
const storage = getStorage().getItem(currentTokenName); const storage = getStorage().getItem(currentTokenName);
namespace = storage?.userRootNamespace; namespace = storage?.userRootNamespace;
// only redirect if something other than nothing // only redirect if something other than nothing
if (namespace) { if (namespace) {
this.transitionTo({ queryParams: { namespace } }); this.transitionTo({ queryParams: { namespace } });
} }
} else if (!namespace && !!this.featureFlagService.managedNamespaceRoot) { } else if (managedRoot !== null) {
this.transitionTo({ queryParams: { namespace: this.featureFlagService.managedNamespaceRoot } }); let managed = getManagedNamespace(namespace, managedRoot);
if (managed !== namespace) {
this.transitionTo({ queryParams: { namespace: managed } });
}
} }
this.namespaceService.setNamespace(namespace); this.namespaceService.setNamespace(namespace);
const id = this.getClusterId(params); const id = this.getClusterId(params);

View File

@ -3,6 +3,7 @@ import { currentURL, visit, fillIn } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit'; import { setupApplicationTest } from 'ember-qunit';
import Pretender from 'pretender'; import Pretender from 'pretender';
import logout from 'vault/tests/pages/logout'; import logout from 'vault/tests/pages/logout';
import { getManagedNamespace } from 'vault/routes/vault/cluster';
const FEATURE_FLAGS_RESPONSE = { const FEATURE_FLAGS_RESPONSE = {
feature_flags: ['VAULT_CLOUD_ADMIN_NAMESPACE'], feature_flags: ['VAULT_CLOUD_ADMIN_NAMESPACE'],
@ -37,7 +38,6 @@ module('Acceptance | Enterprise | Managed namespace root', function (hooks) {
await visit('/vault/auth'); await visit('/vault/auth');
assert.ok(currentURL().startsWith('/vault/auth'), 'Redirected to auth'); assert.ok(currentURL().startsWith('/vault/auth'), 'Redirected to auth');
assert.ok(currentURL().includes('?namespace=admin'), 'with base namespace'); assert.ok(currentURL().includes('?namespace=admin'), 'with base namespace');
assert.dom('[data-test-namespace-toolbar]').doesNotExist('Normal namespace toolbar does not exist'); assert.dom('[data-test-namespace-toolbar]').doesNotExist('Normal namespace toolbar does not exist');
assert.dom('[data-test-managed-namespace-toolbar]').exists('Managed namespace toolbar exists'); assert.dom('[data-test-managed-namespace-toolbar]').exists('Managed namespace toolbar exists');
assert.dom('[data-test-managed-namespace-root]').hasText('/admin', 'Shows /admin namespace prefix'); assert.dom('[data-test-managed-namespace-root]').hasText('/admin', 'Shows /admin namespace prefix');
@ -50,4 +50,32 @@ module('Acceptance | Enterprise | Managed namespace root', function (hooks) {
'Correctly prepends root to namespace' 'Correctly prepends root to namespace'
); );
}); });
test('getManagedNamespace helper works as expected', function (assert) {
let managedNs = getManagedNamespace(null, 'admin');
assert.equal(managedNs, 'admin', 'returns root ns when no namespace present');
managedNs = getManagedNamespace('admin/', 'admin');
assert.equal(managedNs, 'admin', 'returns root ns when matches passed ns');
managedNs = getManagedNamespace('adminfoo/', 'admin');
assert.equal(
managedNs,
'admin/adminfoo/',
'appends passed namespace to root even if it matches without slashes'
);
managedNs = getManagedNamespace('admin/foo/', 'admin');
assert.equal(managedNs, 'admin/foo/', 'returns passed namespace if it starts with root and /');
});
test('it redirects to root prefixed ns when non-root passed', async function (assert) {
await logout.visit();
await visit('/vault/auth?namespace=admindev');
assert.ok(currentURL().startsWith('/vault/auth'), 'Redirected to auth');
assert.ok(
currentURL().includes(`?namespace=${encodeURIComponent('admin/admindev')}`),
'with appended namespace'
);
assert.dom('[data-test-managed-namespace-root]').hasText('/admin', 'Shows /admin namespace prefix');
assert.dom('input#namespace').hasValue('/admindev', 'Input has /dev value');
});
}); });