From 4c80f8d8ff3f2ddc7468283fd1ed77e058f7ab08 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Thu, 11 May 2023 13:55:27 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20initial=20LDAP=20authent?= =?UTF-8?q?ication=20support=20(#1645)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🎸 initial LDAP authentication support --- addons/core/addon/authenticators/ldap.js | 13 ++++ .../form/authenticate/details/index.hbs | 41 ++++++++++ .../{password => details}/index.js | 2 +- .../components/form/authenticate/index.hbs | 1 - .../form/authenticate/ldap/index.hbs | 6 ++ .../form/authenticate/oidc/index.hbs | 1 - .../form/authenticate/password/index.hbs | 33 +------- addons/core/app/authenticators/ldap.js | 6 ++ .../components/form/authenticate/details.js | 6 ++ .../app/components/form/authenticate/ldap.js | 6 ++ .../components/form/authenticate-test.js | 78 +++++++++++++++++++ addons/core/translations/resources/en-us.yaml | 1 + .../scopes/scope/authenticate/method.js | 1 + .../scopes/scope/authenticate/method.js | 1 + 14 files changed, 161 insertions(+), 35 deletions(-) create mode 100644 addons/core/addon/authenticators/ldap.js create mode 100644 addons/core/addon/components/form/authenticate/details/index.hbs rename addons/core/addon/components/form/authenticate/{password => details}/index.js (90%) create mode 100644 addons/core/addon/components/form/authenticate/ldap/index.hbs create mode 100644 addons/core/app/authenticators/ldap.js create mode 100644 addons/core/app/components/form/authenticate/details.js create mode 100644 addons/core/app/components/form/authenticate/ldap.js create mode 100644 addons/core/tests/integration/components/form/authenticate-test.js diff --git a/addons/core/addon/authenticators/ldap.js b/addons/core/addon/authenticators/ldap.js new file mode 100644 index 000000000..9fc6bc734 --- /dev/null +++ b/addons/core/addon/authenticators/ldap.js @@ -0,0 +1,13 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import PasswordAuthenticator from './password'; + +/** + * A simple login_name/password authenticator that authenticates with + * a scope/auth-method endpoint. Authentication occurs on an auth method + * endpoint, while deauthentication occurs on a scope endpoint. + */ +export default class LDAPAuthenticator extends PasswordAuthenticator {} diff --git a/addons/core/addon/components/form/authenticate/details/index.hbs b/addons/core/addon/components/form/authenticate/details/index.hbs new file mode 100644 index 000000000..177e9a2ee --- /dev/null +++ b/addons/core/addon/components/form/authenticate/details/index.hbs @@ -0,0 +1,41 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + + + + {{t 'form.login_name.label'}} + + + + {{t 'form.password.label'}} + + + + + \ No newline at end of file diff --git a/addons/core/addon/components/form/authenticate/password/index.js b/addons/core/addon/components/form/authenticate/details/index.js similarity index 90% rename from addons/core/addon/components/form/authenticate/password/index.js rename to addons/core/addon/components/form/authenticate/details/index.js index 55c931da6..7b1306c64 100644 --- a/addons/core/addon/components/form/authenticate/password/index.js +++ b/addons/core/addon/components/form/authenticate/details/index.js @@ -8,7 +8,7 @@ import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import { run } from '@ember/runloop'; -export default class FormAuthenticatePasswordComponent extends Component { +export default class FormAuthenticateDetailsComponent extends Component { // =properties /** diff --git a/addons/core/addon/components/form/authenticate/index.hbs b/addons/core/addon/components/form/authenticate/index.hbs index 49ee937a1..5a454b6c8 100644 --- a/addons/core/addon/components/form/authenticate/index.hbs +++ b/addons/core/addon/components/form/authenticate/index.hbs @@ -9,7 +9,6 @@ {{component (concat 'form/authenticate/' @model.type) submit=@submit - cancel=false disabled=@disabled }} {{/if}} \ No newline at end of file diff --git a/addons/core/addon/components/form/authenticate/ldap/index.hbs b/addons/core/addon/components/form/authenticate/ldap/index.hbs new file mode 100644 index 000000000..9cb8405e7 --- /dev/null +++ b/addons/core/addon/components/form/authenticate/ldap/index.hbs @@ -0,0 +1,6 @@ +{{! + Copyright (c) HashiCorp, Inc. + SPDX-License-Identifier: MPL-2.0 +}} + + \ No newline at end of file diff --git a/addons/core/addon/components/form/authenticate/oidc/index.hbs b/addons/core/addon/components/form/authenticate/oidc/index.hbs index f83a4b2ba..61ca08cfe 100644 --- a/addons/core/addon/components/form/authenticate/oidc/index.hbs +++ b/addons/core/addon/components/form/authenticate/oidc/index.hbs @@ -6,7 +6,6 @@ diff --git a/addons/core/addon/components/form/authenticate/password/index.hbs b/addons/core/addon/components/form/authenticate/password/index.hbs index 6ca551628..9cb8405e7 100644 --- a/addons/core/addon/components/form/authenticate/password/index.hbs +++ b/addons/core/addon/components/form/authenticate/password/index.hbs @@ -3,35 +3,4 @@ SPDX-License-Identifier: MPL-2.0 }} - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/addons/core/app/authenticators/ldap.js b/addons/core/app/authenticators/ldap.js new file mode 100644 index 000000000..7bd0705ab --- /dev/null +++ b/addons/core/app/authenticators/ldap.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from 'core/authenticators/ldap'; diff --git a/addons/core/app/components/form/authenticate/details.js b/addons/core/app/components/form/authenticate/details.js new file mode 100644 index 000000000..c5bd5a8d4 --- /dev/null +++ b/addons/core/app/components/form/authenticate/details.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from 'core/components/form/authenticate/details'; diff --git a/addons/core/app/components/form/authenticate/ldap.js b/addons/core/app/components/form/authenticate/ldap.js new file mode 100644 index 000000000..26787de39 --- /dev/null +++ b/addons/core/app/components/form/authenticate/ldap.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from 'core/components/form/authenticate/ldap'; diff --git a/addons/core/tests/integration/components/form/authenticate-test.js b/addons/core/tests/integration/components/form/authenticate-test.js new file mode 100644 index 000000000..8a85394c0 --- /dev/null +++ b/addons/core/tests/integration/components/form/authenticate-test.js @@ -0,0 +1,78 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { setupIntl } from 'ember-intl/test-support'; + +module('Integration | Component | form | authenticate', function (hooks) { + setupRenderingTest(hooks); + setupIntl(hooks); + + test('it shows login name and password when LDAP is selected from the list', async function (assert) { + assert.expect(3); + + const store = this.owner.lookup('service:store'); + + this.model = store.createRecord('auth-method', { type: 'ldap' }); + this.submit = () => {}; + this.disabled = () => {}; + + await render(hbs``); + assert.ok(find('.full-width')); + assert.ok(find('.hds-form-text-input')); + assert.strictEqual( + find('button[type="submit"]').textContent.trim(), + 'Sign In' + ); + }); + + test('it shows login name and password when password is selected from the list', async function (assert) { + assert.expect(3); + + const store = this.owner.lookup('service:store'); + + this.model = store.createRecord('auth-method', { type: 'password' }); + this.submit = () => {}; + this.disabled = () => {}; + + await render(hbs``); + assert.ok(find('.full-width')); + assert.ok(find('.hds-form-text-input')); + assert.strictEqual( + find('button[type="submit"]').textContent.trim(), + 'Sign In' + ); + }); + + test('it should only show sign in button when OIDC is selected from the list', async function (assert) { + assert.expect(3); + + const store = this.owner.lookup('service:store'); + + this.model = store.createRecord('auth-method', { type: 'oidc' }); + this.submit = () => {}; + this.disabled = () => {}; + + await render(hbs``); + assert.ok(find('.full-width')); + assert.notOk(find('.hds-form-text-input')); + assert.strictEqual( + find('button[type="submit"]').textContent.trim(), + 'Sign In' + ); + }); +}); diff --git a/addons/core/translations/resources/en-us.yaml b/addons/core/translations/resources/en-us.yaml index f9cba0b87..c57556183 100644 --- a/addons/core/translations/resources/en-us.yaml +++ b/addons/core/translations/resources/en-us.yaml @@ -47,6 +47,7 @@ auth-method: types: password: Password oidc: OIDC + ldap: LDAP actions: create: Create Auth Method delete: Delete Auth Method diff --git a/ui/admin/app/routes/scopes/scope/authenticate/method.js b/ui/admin/app/routes/scopes/scope/authenticate/method.js index 84732cc40..f6532a008 100644 --- a/ui/admin/app/routes/scopes/scope/authenticate/method.js +++ b/ui/admin/app/routes/scopes/scope/authenticate/method.js @@ -63,6 +63,7 @@ export default class ScopesScopeAuthenticateMethodRoute extends Route { const requestCookies = false; switch (authMethod.type) { case 'password': + case 'ldap': await this.session.authenticate( authenticatorName, creds, diff --git a/ui/desktop/app/routes/scopes/scope/authenticate/method.js b/ui/desktop/app/routes/scopes/scope/authenticate/method.js index f01c49aa2..8358f8ef5 100644 --- a/ui/desktop/app/routes/scopes/scope/authenticate/method.js +++ b/ui/desktop/app/routes/scopes/scope/authenticate/method.js @@ -70,6 +70,7 @@ export default class ScopesScopeAuthenticateMethodRoute extends Route { const requestCookies = false; switch (authMethod.type) { case 'password': + case 'ldap': await this.session.authenticate( authenticatorName, creds,