Skip to content

Commit

Permalink
feat: Add SSO SAML metadataUrl support and various improvements (#6139)
Browse files Browse the repository at this point in the history
* feat: add various sso improvements

* fix: remove test button assertion

* fix: fix type imports

* test: attempt fixing unit tests

* fix: changed to using useToast for error toasts

* Minor copy tweaks and swapped buttons position.

* fix locale ref

* align error with UI wording

* simplify saving ux

* fix pretty

* fix: update saml sso setting saving

* fix: undo try/catch changes when saving saml config

* metadata url tab selected at first

* chore: fix linting issue

* test: fix activation checkbox test

---------

Co-authored-by: Giulio Andreini <[email protected]>
Co-authored-by: Michael Auerswald <[email protected]>
Co-authored-by: Romain Minaud <[email protected]>
  • Loading branch information
4 people authored May 23, 2023
1 parent 4b85433 commit e3a53fd
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 118 deletions.
2 changes: 1 addition & 1 deletion packages/cli/src/controllers/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class AuthController {
user = preliminaryUser;
usedAuthenticationMethod = 'email';
} else {
throw new AuthError('SAML is enabled, please log in with SAML');
throw new AuthError('SSO is enabled, please log in with SSO');
}
} else if (isLdapCurrentAuthenticationMethod()) {
user = await handleLdapLogin(email, password);
Expand Down
2 changes: 2 additions & 0 deletions packages/editor-ui/src/__tests__/server/endpoints/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { routesForCredentials } from './credential';
import { routesForCredentialTypes } from './credentialType';
import { routesForVariables } from './variable';
import { routesForSettings } from './settings';
import { routesForSSO } from './sso';

const endpoints: Array<(server: Server) => void> = [
routesForCredentials,
routesForCredentialTypes,
routesForUsers,
routesForVariables,
routesForSettings,
routesForSSO,
];

export { endpoints };
36 changes: 36 additions & 0 deletions packages/editor-ui/src/__tests__/server/endpoints/sso.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Server, Request } from 'miragejs';
import { Response } from 'miragejs';
import type { SamlPreferences, SamlPreferencesExtractedData } from '@/Interface';
import { faker } from '@faker-js/faker';
import type { AppSchema } from '@/__tests__/server/types';
import { jsonParse } from 'n8n-workflow';

let samlConfig: SamlPreferences & SamlPreferencesExtractedData = {
metadata: '<?xml version="1.0"?>',
metadataUrl: '',
entityID: faker.internet.url(),
returnUrl: faker.internet.url(),
};

export function routesForSSO(server: Server) {
server.get('/rest/sso/saml/config', () => {
return new Response(200, {}, { data: samlConfig });
});

server.post('/rest/sso/saml/config', (schema: AppSchema, request: Request) => {
const requestBody = jsonParse(request.requestBody) as Partial<
SamlPreferences & SamlPreferencesExtractedData
>;

samlConfig = {
...samlConfig,
...requestBody,
};

return new Response(200, {}, { data: samlConfig });
});

server.get('/rest/sso/saml/config/test', () => {
return new Response(200, {}, { data: '<?xml version="1.0"?>' });
});
}
2 changes: 1 addition & 1 deletion packages/editor-ui/src/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { UserManagementAuthenticationMethod } from '@/Interface';
import { render } from '@testing-library/vue';
import { PiniaVuePlugin } from 'pinia';

export const retry = async (assertion: () => any, { interval = 20, timeout = 200 } = {}) => {
export const retry = async (assertion: () => any, { interval = 20, timeout = 1000 } = {}) => {
return new Promise((resolve, reject) => {
const startTime = Date.now();

Expand Down
22 changes: 16 additions & 6 deletions packages/editor-ui/src/plugins/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1797,22 +1797,32 @@
"settings.ldap.section.synchronization.title": "Synchronization",
"settings.sso": "SSO",
"settings.sso.title": "Single Sign On",
"settings.sso.subtitle": "SAML 2.0",
"settings.sso.info": "SAML SSO (Security Assertion Markup Language Single Sign-On) is a type of authentication process that enables users to access multiple applications with a single set of login credentials. {link}",
"settings.sso.info.link": "More info.",
"settings.sso.subtitle": "SAML 2.0 Configuration",
"settings.sso.info": "Activate SAML SSO to enable passwordless login via your existing user management tool and enhance security through unified authentication.",
"settings.sso.info.link": "Learn how to configure SAML 2.0.",
"settings.sso.activation.tooltip": "You need to save the settings first before activating SAML",
"settings.sso.activated": "Activated",
"settings.sso.deactivated": "Deactivated",
"settings.sso.settings.redirectUrl.label": "Redirect URL",
"settings.sso.settings.redirectUrl.copied": "Redirect URL copied to clipboard",
"settings.sso.settings.redirectUrl.help": "Save the Redirect URL as you’ll need it to configure these in the SAML provider’s settings.",
"settings.sso.settings.redirectUrl.help": "Copy the Redirect URL to configure your SAML provider",
"settings.sso.settings.entityId.label": "Entity ID",
"settings.sso.settings.entityId.copied": "Entity ID copied to clipboard",
"settings.sso.settings.entityId.help": "Save the Entity URL as you’ll need it to configure these in the SAML provider’s settings.",
"settings.sso.settings.entityId.help": "Copy the Entity ID URL to configure your SAML provider",
"settings.sso.settings.ips.label": "Identity Provider Settings",
"settings.sso.settings.ips.help": "Add the raw Metadata XML provided by your Identity Provider",
"settings.sso.settings.ips.xml.help": "Paste here the raw Metadata XML provided by your Identity Provider",
"settings.sso.settings.ips.url.help": "Paste here the Internet Provider Metadata URL",
"settings.sso.settings.ips.url.placeholder": "e.g. https://samltest.id/saml/idp",
"settings.sso.settings.ips.options.url": "Metadata URL",
"settings.sso.settings.ips.options.xml": "XML",
"settings.sso.settings.test": "Test settings",
"settings.sso.settings.save": "Save settings",
"settings.sso.settings.save.activate.title": "Test and activate SAML SSO",
"settings.sso.settings.save.activate.message": "SAML SSO configuration saved successfully. Test your SAML SSO settings first, then activate to enable single sign-on for your organization.",
"settings.sso.settings.save.activate.cancel": "Cancel",
"settings.sso.settings.save.activate.test": "Test settings",
"settings.sso.settings.save.error": "Error saving SAML SSO configuration",
"settings.sso.settings.footer.hint": "Don't forget to activate SAML SSO once you've saved the settings.",
"settings.sso.actionBox.title": "Available on Enterprise plan",
"settings.sso.actionBox.description": "Use Single Sign On to consolidate authentication into a single platform to improve security and agility.",
"settings.sso.actionBox.buttonText": "See plans",
Expand Down
11 changes: 10 additions & 1 deletion packages/editor-ui/src/stores/sso.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useSettingsStore } from '@/stores/settings.store';
import * as ssoApi from '@/api/sso';
import type { SamlPreferences } from '@/Interface';
import { updateCurrentUser } from '@/api/users';
import type { SamlPreferencesExtractedData } from '@/Interface';
import { useUsersStore } from '@/stores/users.store';

export const useSSOStore = defineStore('sso', () => {
Expand All @@ -15,10 +16,13 @@ export const useSSOStore = defineStore('sso', () => {

const state = reactive({
loading: false,
samlConfig: undefined as (SamlPreferences & SamlPreferencesExtractedData) | undefined,
});

const isLoading = computed(() => state.loading);

const samlConfig = computed(() => state.samlConfig);

const setLoading = (loading: boolean) => {
state.loading = loading;
};
Expand Down Expand Up @@ -56,7 +60,11 @@ export const useSSOStore = defineStore('sso', () => {
ssoApi.toggleSamlConfig(rootStore.getRestApiContext, { loginEnabled: enabled });

const getSamlMetadata = async () => ssoApi.getSamlMetadata(rootStore.getRestApiContext);
const getSamlConfig = async () => ssoApi.getSamlConfig(rootStore.getRestApiContext);
const getSamlConfig = async () => {
const samlConfig = await ssoApi.getSamlConfig(rootStore.getRestApiContext);
state.samlConfig = samlConfig;
return samlConfig;
};
const saveSamlConfig = async (config: SamlPreferences) =>
ssoApi.saveSamlConfig(rootStore.getRestApiContext, config);
const testSamlConfig = async () => ssoApi.testSamlConfig(rootStore.getRestApiContext);
Expand All @@ -77,6 +85,7 @@ export const useSSOStore = defineStore('sso', () => {
isEnterpriseSamlEnabled,
isDefaultAuthenticationSaml,
showSsoLoginButton,
samlConfig,
getSSORedirectUrl,
getSamlMetadata,
getSamlConfig,
Expand Down
Loading

0 comments on commit e3a53fd

Please sign in to comment.