diff --git a/api-tests/core/admin/ee/provider-options.test.api.js b/api-tests/core/admin/ee/provider-options.test.api.js new file mode 100644 index 0000000000..f06fcff90e --- /dev/null +++ b/api-tests/core/admin/ee/provider-options.test.api.js @@ -0,0 +1,142 @@ +'use strict'; + +const { createStrapiInstance } = require('api-tests/strapi'); +const { createAuthRequest, createRequest } = require('api-tests/request'); +const { createUtils, describeOnCondition } = require('api-tests/utils'); + +const edition = process.env.STRAPI_DISABLE_EE === 'true' ? 'CE' : 'EE'; + +let strapi; +let utils; +const requests = { + public: undefined, + admin: undefined, + noPermissions: undefined, +}; + +const localData = { + restrictedUser: null, + restrictedRole: null, +}; + +const restrictedUser = { + email: 'restricted@user.io', + password: 'Restricted123', +}; + +const restrictedRole = { + name: 'restricted-role', + description: '', +}; + +const createFixtures = async () => { + const role = await utils.createRole(restrictedRole); + const user = await utils.createUserIfNotExists({ + ...restrictedUser, + roles: [role.id], + }); + + localData.restrictedUser = user; + localData.restrictedRole = role; + + return { role, user }; +}; + +const deleteFixtures = async () => { + await utils.deleteUserById(localData.restrictedUser.id); + await utils.deleteRolesById([localData.restrictedRole.id]); +}; + +describeOnCondition(edition === 'EE')('SSO Provider Options', () => { + let hasSSO; + + beforeAll(async () => { + strapi = await createStrapiInstance(); + utils = createUtils(strapi); + // eslint-disable-next-line node/no-extraneous-require + hasSSO = require('@strapi/strapi/lib/utils/ee').features.isEnabled('sso'); + + await createFixtures(); + + requests.public = createRequest({ strapi }); + requests.admin = await createAuthRequest({ strapi }); + requests.noPermissions = await createAuthRequest({ strapi, userInfo: restrictedUser }); + }); + + afterAll(async () => { + await deleteFixtures(); + await strapi.destroy(); + }); + + describe('Get provider options', () => { + test('Get the provider options as public user gives 401', async () => { + const res = await requests.public.get('/admin/providers/options'); + expect(res.status).toEqual(401); + }); + + test('Get the provider options with no permissions gives 403', async () => { + const res = await requests.noPermissions.get('/admin/providers/options'); + expect(res.status).toEqual(403); + }); + + test('Get the provider options as admin succeeds', async () => { + const res = await requests.admin.get('/admin/providers/options'); + if (hasSSO) { + expect(res.status).toBe(200); + const { data } = JSON.parse(res.text); + const keys = Object.keys(data); + expect(keys).toContain('autoRegister'); + expect(keys).toContain('ssoLockedRoles'); + expect(keys).toContain('defaultRole'); + } else { + expect(res.status).toBe(404); + expect(Array.isArray(res.body)).toBeFalsy(); + } + }); + }); + + describe('ssoLockedRoles', () => { + test.each([ + ['empty array', []], + ['null', null], + ['array of roles', [1]], + ])('can be %s', async (name, value) => { + const newData = { + ssoLockedRoles: value, + defaultRole: localData.restrictedRole.id, // TODO: there seems to be a bug with not setting a default role + autoRegister: false, + }; + const res = await requests.admin.put('/admin/providers/options', { + body: newData, + }); + if (hasSSO) { + expect(res.status).toEqual(200); + const parsed = JSON.parse(res.text); + expect(parsed.data).toMatchObject(newData); + } else { + expect(res.status).toBe(404); + expect(Array.isArray(res.body)).toBeFalsy(); + } + }); + + test.each([ + ['invalid role id', [999]], + ['string', '1'], + ['object', { role: 1 }], + ])('cannot be %s', async (name, value) => { + const res = await requests.admin.put('/admin/providers/options', { + body: { + ssoLockedRoles: value, + defaultRole: localData.restrictedRole.id, // TODO: there seems to be a bug with not setting a default role + autoRegister: false, + }, + }); + if (hasSSO) { + expect(res.status).toEqual(400); + } else { + expect(res.status).toBe(404); + expect(Array.isArray(res.body)).toBeFalsy(); + } + }); + }); +}); diff --git a/packages/core/admin/ee/admin/pages/SettingsPage/pages/SingleSignOn/utils/schema.js b/packages/core/admin/ee/admin/pages/SettingsPage/pages/SingleSignOn/utils/schema.js index 89136c0717..515a111c07 100644 --- a/packages/core/admin/ee/admin/pages/SettingsPage/pages/SingleSignOn/utils/schema.js +++ b/packages/core/admin/ee/admin/pages/SettingsPage/pages/SingleSignOn/utils/schema.js @@ -6,11 +6,14 @@ const schema = yup.object().shape({ defaultRole: yup.mixed().when('autoRegister', (value, initSchema) => { return value ? initSchema.required(translatedErrors.required) : initSchema.nullable(); }), - ssoLockedRoles: yup.array().of( - yup.mixed().when('ssoLockedRoles', (value, initSchema) => { - return value ? initSchema.required(translatedErrors.required) : initSchema.nullable(); - }) - ), + ssoLockedRoles: yup + .array() + .nullable() + .of( + yup.mixed().when('ssoLockedRoles', (value, initSchema) => { + return value ? initSchema.required(translatedErrors.required) : initSchema.nullable(); + }) + ), }); export default schema; diff --git a/packages/core/admin/ee/server/validation/authentication.js b/packages/core/admin/ee/server/validation/authentication.js index 351a65fed9..c498a4b10c 100644 --- a/packages/core/admin/ee/server/validation/authentication.js +++ b/packages/core/admin/ee/server/validation/authentication.js @@ -10,14 +10,20 @@ const providerOptionsUpdateSchema = yup.object().shape({ .test('is-valid-role', 'You must submit a valid default role', (roleId) => { return strapi.admin.services.role.exists({ id: roleId }); }), - ssoLockedRoles: yup.array().of( - yup - .strapiID() - .required() - .test('is-valid-role', 'You must submit a valid role for the SSO Locked roles', (roleId) => { - return strapi.admin.services.role.exists({ id: roleId }); - }) - ), + ssoLockedRoles: yup + .array() + .nullable() + .of( + yup + .strapiID() + .test( + 'is-valid-role', + 'You must submit a valid role for the SSO Locked roles', + (roleId) => { + return strapi.admin.services.role.exists({ id: roleId }); + } + ) + ), }); module.exports = {