feat: 🎸 Allow prompts in oidc auth method form (#2007)

* feat: 🎸 Allow prompts in OIDC auth method form
This commit is contained in:
Dharini Jeeva authored and GitHub committed 2023-11-28 11:59:16 -08:00
1 parent 02a89bd7ba
commit 3f2f2ba756
12 files changed
+115 -2

No files matched your search

@@ -158,6 +158,13 @@ export default class GeneratedAuthMethodModel extends BaseModel {
})
account_claim_maps;
@attr('string-array', {
for: 'oidc',
emptyArrayIfMissing: true,
isNestedAttribute: true,
})
prompts;
// =attributes(ldap)
@attr('boolean', {
+1
View File
@@ -37,6 +37,7 @@ export const options = {
account_claim_maps: {
to: ['sub', 'name', 'email'],
},
prompts: ['none', 'consent', 'select_account', 'login'],
},
ldap: {
account_attribute_maps: {
@@ -42,6 +42,7 @@ export default Factory.extend({
signing_algorithms: ['RS256', 'RS384'],
allowed_audiences: ['www.alice.com', 'www.alice.com/admin'],
idp_ca_certs: ['certificate-1234', 'certificate-5678'],
prompts: ['consent'],
};
break;
case TYPE_AUTH_METHOD_LDAP:
@@ -165,6 +165,7 @@ module('Unit | Serializer | application', function (hooks) {
dry_run: true,
issuer: 'http://www.example.net',
max_age: 500,
prompts: [{ value: 'consent' }],
});
let serializedRecord = record.serialize();
@@ -186,6 +187,7 @@ module('Unit | Serializer | application', function (hooks) {
dry_run: true,
issuer: 'http://www.example.net',
max_age: 500,
prompts: ['consent'],
},
});
});
@@ -65,6 +65,7 @@ module('Unit | Serializer | auth method', function (hooks) {
dry_run: true,
issuer: 'http://www.example.net',
max_age: 500,
prompts: [{ value: 'none' }],
});
let serializedRecord = record.serialize();
@@ -86,6 +87,7 @@ module('Unit | Serializer | auth method', function (hooks) {
dry_run: true,
issuer: 'http://www.example.net',
max_age: 500,
prompts: ['none'],
},
});
});
@@ -180,6 +182,7 @@ module('Unit | Serializer | auth method', function (hooks) {
dry_run: true,
issuer: 'http://www.example.net',
max_age: 500,
prompts: [{ value: 'consent' }],
});
let serializedRecord = record.serialize();
@@ -200,6 +203,7 @@ module('Unit | Serializer | auth method', function (hooks) {
dry_run: true,
issuer: 'http://www.example.net',
max_age: 500,
prompts: ['consent'],
},
});
});
@@ -397,6 +401,7 @@ module('Unit | Serializer | auth method', function (hooks) {
issuer: issuer,
max_age: maxAge,
client_secret: 'secret123',
prompts: ['consent'],
},
version: 1,
type: TYPE_AUTH_METHOD_OIDC,
@@ -410,6 +415,7 @@ module('Unit | Serializer | auth method', function (hooks) {
allowed_audiences,
signing_algorithms,
idp_ca_certs,
prompts,
} = record;
assert.deepEqual(account_claim_maps, [
{ from: 'from', to: 'to' },
@@ -429,6 +435,7 @@ module('Unit | Serializer | auth method', function (hooks) {
{ value: 'certificate-5678' },
]);
assert.strictEqual(record.api_url_prefix, apiUrlPrefix);
assert.deepEqual(prompts, [{ value: 'consent' }]);
assert.strictEqual(record.client_id, clientId);
assert.strictEqual(
record.disable_discovered_config_validation,
+3
View File
@@ -119,6 +119,9 @@ to_claim:
signing_algorithms:
label: Signing Algorithms
help: The signing algorithms allowed for the auth method.
prompts:
label: Prompts
help: The prompts allowed for an oidc auth method.
algorithm:
label: Algorithm
subject:
@@ -147,6 +147,18 @@ auth-method:
account_attribute_maps:
label: Account Attribute Maps
help: Attribute maps from custom attributes to the standard fullname and email account attributes. These maps are represented as key=value where the key equals the from_attribute, and the value equals the to_attribute. For example, "preferredName=fullName".
consent:
label: Consent
help: Always require the user to explicitly consent to scopes requested
select_account:
label: Select Account
help: Allow the user to select from multiple accounts from this provider
login:
label: Login
help: Always require the user to log in to this auth provider
none:
label: None
help: Skip prompts if the user is already signed in and has granted consent
section:
connection:
title: Connection
@@ -528,6 +528,34 @@
{{/if}}
</form.input>
<Hds::Form::Checkbox::Group
class='oidc-prompts'
@isOptional={{true}}
@name='prompts'
disabled={{form.disabled}}
as |G|
>
<G.Legend>{{t 'form.prompts.label'}}</G.Legend>
<G.HelperText>{{t 'form.prompts.help'}}</G.HelperText>
{{#each this.prompts as |prompt|}}
<G.Checkbox::Field
@id={{prompt}}
checked={{includes prompt this.selectedPrompts}}
{{on 'change' (fn this.updatePrompt prompt)}}
as |F|
>
<F.Label>
{{t (concat 'resources.auth-method.form.' prompt '.label')}}
</F.Label>
<F.HelperText>
{{t (concat 'resources.auth-method.form.' prompt '.help')}}
</F.HelperText>
</G.Checkbox::Field>
{{/each}}
</Hds::Form::Checkbox::Group>
{{#unless @model.isNew}}
<form.input
@value={{@model.callback_url}}
@@ -537,6 +565,7 @@
@disabled={{true}}
/>
{{/unless}}
{{#if (can 'save model' @model)}}
<form.actions
@enableEditText={{t 'actions.edit-form'}}
@@ -5,6 +5,8 @@
import Component from '@glimmer/component';
import { options } from 'api/models/auth-method';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
export default class FormAuthMethodOidcComponent extends Component {
// =attributes
@@ -27,4 +29,41 @@ export default class FormAuthMethodOidcComponent extends Component {
* @type {string}
*/
newSigningAlgorithm = options.oidc.signing_algorithms[0];
/**
* @type {string}
*/
prompts = options.oidc.prompts;
@tracked selectedPrompts = this.parsePromptsArray();
/**
* @returns {string}
*/
parsePromptsArray() {
return this.args.model.prompts?.map((item) => item.value) ?? [];
}
//actions
/**
* @param {string} option
* @param {object} event
*/
@action
updatePrompt(value, event) {
const currentSelection = { value };
const previousSelection = this.args.model.prompts || [];
// Add the selected option to the model, only when the checkbox is in checked state
if (event.target.checked) {
this.args.model.prompts = [...previousSelection, currentSelection];
} else {
// When the checkbox is unchecked, remove the option form the exisiting list
const removeSelection = previousSelection.filter(
(prompt) => prompt.value !== value,
);
this.args.model.prompts = [...removeSelection];
}
}
}
+8
View File
@@ -317,6 +317,14 @@
}
}
/* stylelint-disable selector-class-pattern */
.oidc-prompts {
.hds-form-group__control-field {
margin-bottom: 0.5rem;
}
}
/* stylelint-enable selector-class-pattern */
.worker-create-section {
border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-3);
border-radius: sizing.rems(xxs);
@@ -108,7 +108,7 @@ module('Acceptance | auth-methods | create', function (hooks) {
});
test('Users can create new oidc auth method', async function (assert) {
assert.expect(12);
assert.expect(13);
const count = getAuthMethodsCount();
await visit(`${urls.authMethods}/new?type=oidc`);
@@ -134,6 +134,7 @@ module('Acceptance | auth-methods | create', function (hooks) {
await click(IDP_CERTS_BTN_SELECTOR);
await fillIn('[name="max_age"]', '5');
await fillIn('[name="api_url_prefix"]', 'api_url_prefix');
await click('[id="consent"]', 'consent');
await click(SAVE_BTN_SELECTOR);
assert.strictEqual(getAuthMethodsCount(), count + 1);
@@ -153,6 +154,7 @@ module('Acceptance | auth-methods | create', function (hooks) {
assert.deepEqual(authMethod.attributes.idp_ca_certs, ['certificates']);
assert.strictEqual(authMethod.attributes.max_age, 5);
assert.strictEqual(authMethod.attributes.api_url_prefix, 'api_url_prefix');
assert.deepEqual(authMethod.attributes.prompts, ['consent']);
});
test('Users can create a new ldap auth method', async function (assert) {
@@ -108,7 +108,7 @@ module('Acceptance | auth-methods | update', function (hooks) {
});
test('can update an oidc auth method and save changes', async function (assert) {
assert.expect(11);
assert.expect(12);
instances.authMethod = this.server.create('auth-method', {
scope: instances.scopes.org,
type: TYPE_AUTH_METHOD_OIDC,
@@ -173,6 +173,7 @@ module('Acceptance | auth-methods | update', function (hooks) {
await click(IDP_CERTS_BTN_SELECTOR);
await fillIn('[name="max_age"]', '5');
await fillIn('[name="api_url_prefix"]', 'api_url_prefix');
await click('[id="none"]', 'none');
await click('form [type="submit"]:not(:disabled)');
const authMethod = this.server.schema.authMethods.findBy({ name });
@@ -191,6 +192,7 @@ module('Acceptance | auth-methods | update', function (hooks) {
assert.deepEqual(authMethod.attributes.idp_ca_certs, ['certificates']);
assert.strictEqual(authMethod.attributes.max_age, 5);
assert.strictEqual(authMethod.attributes.api_url_prefix, 'api_url_prefix');
assert.deepEqual(authMethod.attributes.prompts, ['consent', 'none']);
});
test('can update an ldap auth method and save changes', async function (assert) {