UI/Remove token_type field from token auth method (#12904)
* chane form field to angle bracket syntax * computes tuneAttrs depending on auth method type * make all attrs linkable * delete token_type for token auth methods before save * adds changelog * adds copy to unsupported auth methods * adds doc link to copy * adds test for linkable auth method list
This commit is contained in:
parent
353e8a312f
commit
ab1fd3255b
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
ui: Removes ability to tune token_type for token auth methods
|
||||
```
|
|
@ -22,6 +22,12 @@ export default AuthConfigComponent.extend({
|
|||
saveModel: task(function*() {
|
||||
let data = this.model.config.serialize();
|
||||
data.description = this.model.description;
|
||||
|
||||
// token_type should not be tuneable for the token auth method, default is 'default-service'
|
||||
if (this.model.type === 'token') {
|
||||
delete data.token_type;
|
||||
}
|
||||
|
||||
try {
|
||||
yield this.model.tune(data);
|
||||
} catch (err) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { helper as buildHelper } from '@ember/component/helper';
|
||||
|
||||
const MANAGED_AUTH_BACKENDS = ['okta', 'radius', 'ldap', 'cert', 'userpass'];
|
||||
const MANAGED_AUTH_BACKENDS = ['cert', 'userpass', 'ldap', 'okta', 'radius'];
|
||||
|
||||
export function supportedManagedAuthBackends() {
|
||||
return MANAGED_AUTH_BACKENDS;
|
||||
|
|
|
@ -49,14 +49,25 @@ let ModelExport = Model.extend(Validations, {
|
|||
return this.local ? 'local' : 'replicated';
|
||||
}),
|
||||
|
||||
tuneAttrs: computed(function() {
|
||||
return expandAttributeMeta(this, [
|
||||
'description',
|
||||
'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
|
||||
]);
|
||||
tuneAttrs: computed('path', function() {
|
||||
let { methodType } = this;
|
||||
let tuneAttrs;
|
||||
// token_type should not be tuneable for the token auth method
|
||||
if (methodType === 'token') {
|
||||
tuneAttrs = [
|
||||
'description',
|
||||
'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
|
||||
];
|
||||
} else {
|
||||
tuneAttrs = [
|
||||
'description',
|
||||
'config.{listingVisibility,defaultLeaseTtl,maxLeaseTtl,tokenType,auditNonHmacRequestKeys,auditNonHmacResponseKeys,passthroughRequestHeaders}',
|
||||
];
|
||||
}
|
||||
return expandAttributeMeta(this, tuneAttrs);
|
||||
}),
|
||||
|
||||
//sys/mounts/auth/[auth-path]/tune.
|
||||
// sys/mounts/auth/[auth-path]/tune.
|
||||
tune: memberAction({
|
||||
path: 'tune',
|
||||
type: 'post',
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<MessageError @model={{model}} @errorMessage={{model.errorMessage}}/>
|
||||
<NamespaceReminder @mode="save" @noun="Auth Method" />
|
||||
{{#each model.tuneAttrs as |attr|}}
|
||||
{{form-field data-test-field attr=attr model=model}}
|
||||
<FormField data-test-field @attr={{attr}} @model={{model}} />
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="field is-grouped box is-fullwidth is-bottomless">
|
||||
|
@ -16,4 +16,4 @@
|
|||
Update Options
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
@ -17,7 +17,16 @@
|
|||
</h1>
|
||||
</p.levelLeft>
|
||||
</PageHeader>
|
||||
|
||||
{{#if (not (contains model.type (supported-managed-auth-backends)))}}
|
||||
<div class="has-text-grey has-top-bottom-margin" data-test-doc-link>
|
||||
The Vault UI only supports configuration for this authentication method.
|
||||
For management, the <DocLink @path="/api/auth">API or CLI</DocLink> should be used.
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{section-tabs model "authShow" paths}}
|
||||
|
||||
{{#if (eq section "configuration")}}
|
||||
<Toolbar>
|
||||
<ToolbarActions>
|
||||
|
|
|
@ -15,43 +15,45 @@
|
|||
</Toolbar>
|
||||
|
||||
{{#each (sort-by "path" model) as |method|}}
|
||||
{{#if (contains method.methodType (supported-managed-auth-backends))}}
|
||||
<LinkedBlock @params={{array
|
||||
<LinkedBlock @params={{array
|
||||
"vault.cluster.access.method"
|
||||
method.id}} class="list-item-row" data-test-auth-backend-link={{method.id}}>
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<div>
|
||||
<ToolTip @horizontalPosition="left" as |T|>
|
||||
<T.trigger>
|
||||
<Icon @glyph={{if
|
||||
(or
|
||||
(find-by "type" method.methodType (mountable-auth-methods))
|
||||
(eq method.methodType "token")
|
||||
)
|
||||
method.methodType
|
||||
"auth"
|
||||
}} @size="l" class="has-text-grey-light" />
|
||||
</T.trigger>
|
||||
<T.content @class="tool-tip">
|
||||
<div class="box">
|
||||
{{method.methodType}}
|
||||
</div>
|
||||
</T.content>
|
||||
</ToolTip>
|
||||
<span data-test-path data-test-id={{method.id}} class="has-text-weight-semibold has-text-black">
|
||||
{{method.path}}
|
||||
</span>
|
||||
<br />
|
||||
<code class="has-text-grey is-size-8">
|
||||
{{method.accessor}}
|
||||
</code>
|
||||
</div>
|
||||
method.id}} class="list-item-row"
|
||||
data-test-auth-backend-link={{method.id}}
|
||||
>
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<div>
|
||||
<ToolTip @horizontalPosition="left" as |T|>
|
||||
<T.trigger>
|
||||
<Icon @size="l" class="has-text-grey-light"
|
||||
@glyph={{if
|
||||
(or
|
||||
(find-by "type" method.methodType (mountable-auth-methods))
|
||||
(eq method.methodType "token")
|
||||
)
|
||||
method.methodType
|
||||
"auth"}}
|
||||
/>
|
||||
</T.trigger>
|
||||
<T.content @class="tool-tip">
|
||||
<div class="box">
|
||||
{{method.methodType}}
|
||||
</div>
|
||||
</T.content>
|
||||
</ToolTip>
|
||||
<span data-test-path data-test-id={{method.id}} class="has-text-weight-semibold has-text-black">
|
||||
{{method.path}}
|
||||
</span>
|
||||
<br />
|
||||
<code class="has-text-grey is-size-8">
|
||||
{{method.accessor}}
|
||||
</code>
|
||||
</div>
|
||||
<div class="level-right is-flex is-paddingless is-marginless">
|
||||
<div class="level-item">
|
||||
<PopupMenu @name="auth-backend-nav">
|
||||
<Confirm as |c|>
|
||||
</div>
|
||||
<div class="level-right is-flex is-paddingless is-marginless">
|
||||
<div class="level-item">
|
||||
<PopupMenu @name="auth-backend-nav">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
|
@ -69,88 +71,21 @@
|
|||
|
||||
{{#if (and (not-eq method.methodType 'token') method.canDisable)}}
|
||||
<li class="action">
|
||||
<c.Message
|
||||
@id={{method.id}}
|
||||
@title="Disable method?"
|
||||
@message="This may affect access to Vault data."
|
||||
@triggerText="Disable"
|
||||
@onConfirm={{perform disableMethod method}}>
|
||||
</c.Message>
|
||||
<c.Message
|
||||
@id={{method.id}}
|
||||
@title="Disable method?"
|
||||
@message="This may affect access to Vault data."
|
||||
@triggerText="Disable"
|
||||
@onConfirm={{perform disableMethod method}}>
|
||||
</c.Message>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LinkedBlock>
|
||||
{{else}}
|
||||
<div class="list-item-row" data-test-auth-backend-link={{method.id}}>
|
||||
<div class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<div>
|
||||
<ToolTip @horizontalPosition="left" as |T|>
|
||||
<T.trigger>
|
||||
<Icon @glyph={{if
|
||||
(or
|
||||
(find-by "type" method.methodType (mountable-auth-methods))
|
||||
(eq method.methodType "token")
|
||||
)
|
||||
method.methodType
|
||||
"auth"
|
||||
}} @size="l" class="has-text-grey-light" />
|
||||
</T.trigger>
|
||||
<T.content @class="tool-tip">
|
||||
<div class="box">
|
||||
{{method.methodType}}
|
||||
</div>
|
||||
</T.content>
|
||||
</ToolTip>
|
||||
<span data-test-path data-test-id={{method.id}} class="has-text-weight-semibold has-text-grey">
|
||||
{{method.path}}
|
||||
</span>
|
||||
<br />
|
||||
<code class="has-text-grey is-size-8">
|
||||
{{method.accessor}}
|
||||
</code>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level-right is-flex is-paddingless is-marginless">
|
||||
<div class="level-item">
|
||||
<PopupMenu @name="auth-backend-nav">
|
||||
<Confirm as |c|>
|
||||
<nav class="menu">
|
||||
<ul class="menu-list">
|
||||
<li>
|
||||
<LinkTo @route="vault.cluster.access.method.section" @models={{array method.id "configuration"}}>
|
||||
View configuration
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{#if method.canEdit}}
|
||||
<li>
|
||||
<LinkTo @route="vault.cluster.settings.auth.configure" @model={{method.id}}>
|
||||
Edit configuration
|
||||
</LinkTo>
|
||||
</li>
|
||||
{{/if}}
|
||||
|
||||
{{#if (and (not-eq method.methodType 'token') method.canDisable)}}
|
||||
<li class="action">
|
||||
<c.Message @id={{method.id}} @title="Disable method?"
|
||||
@message="This may affect access to Vault data." @triggerText="Disable"
|
||||
@onConfirm={{perform disableMethod method}}>
|
||||
</c.Message>
|
||||
</li>
|
||||
{{/if}}
|
||||
</ul>
|
||||
</nav>
|
||||
</Confirm>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</Confirm>
|
||||
</PopupMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</LinkedBlock>
|
||||
{{/each}}
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
{{auth-config-form/options model.model}}
|
||||
{{else}}
|
||||
{{auth-config-form/config model.model}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { click, fillIn, settled, visit, triggerKeyEvent } from '@ember/test-helpers';
|
||||
import { click, findAll, fillIn, settled, visit, triggerKeyEvent } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import authPage from 'vault/tests/pages/auth';
|
||||
import logout from 'vault/tests/pages/logout';
|
||||
import enablePage from 'vault/tests/pages/settings/auth/enable';
|
||||
import { supportedAuthBackends } from 'vault/helpers/supported-auth-backends';
|
||||
import { supportedManagedAuthBackends } from 'vault/helpers/supported-managed-auth-backends';
|
||||
|
||||
module('Acceptance | userpass secret backend', function(hooks) {
|
||||
module('Acceptance | auth backend list', function(hooks) {
|
||||
setupApplicationTest(hooks);
|
||||
|
||||
hooks.beforeEach(function() {
|
||||
|
@ -16,7 +18,7 @@ module('Acceptance | userpass secret backend', function(hooks) {
|
|||
return logout.visit();
|
||||
});
|
||||
|
||||
test('userpass backend', async function(assert) {
|
||||
test('userpass secret backend', async function(assert) {
|
||||
let n = Math.random();
|
||||
const path1 = `userpass-${++n}`;
|
||||
const path2 = `userpass-${++n}`;
|
||||
|
@ -73,4 +75,39 @@ module('Acceptance | userpass secret backend', function(hooks) {
|
|||
.dom('[data-test-list-item-content]')
|
||||
.hasText(user1, 'first user created shows in current auth list');
|
||||
});
|
||||
|
||||
test('auth methods are linkable and link to correct view', async function(assert) {
|
||||
await visit('/vault/access');
|
||||
await settled();
|
||||
let supportManaged = supportedManagedAuthBackends();
|
||||
let backends = supportedAuthBackends();
|
||||
|
||||
for (let backend of backends) {
|
||||
let { type } = backend;
|
||||
|
||||
if (type !== 'token') {
|
||||
await enablePage.enable(type, type);
|
||||
}
|
||||
await settled();
|
||||
await visit('/vault/access');
|
||||
|
||||
// all auth methods should be linkable
|
||||
await click(`[data-test-auth-backend-link="${type}"]`);
|
||||
|
||||
if (!supportManaged.includes(type)) {
|
||||
assert.equal(findAll('[data-test-auth-section-tab]').length, 1);
|
||||
assert
|
||||
.dom('[data-test-auth-section-tab]')
|
||||
.hasText('Configuration', `only shows configuration tab for ${type} auth method`);
|
||||
assert.dom('[data-test-doc-link] .doc-link').exists(`includes doc link for ${type} auth method`);
|
||||
} else {
|
||||
// managed auth methods should have more than 1 tab
|
||||
assert.notEqual(
|
||||
findAll('[data-test-auth-section-tab]').length,
|
||||
1,
|
||||
`has management tabs for ${type} auth method`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue