diff --git a/packages/backend/src/controllers/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js b/packages/backend/src/controllers/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js new file mode 100644 index 00000000..7297b66f --- /dev/null +++ b/packages/backend/src/controllers/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js @@ -0,0 +1,11 @@ +import { renderObject } from '../../../../helpers/renderer.js'; +import SamlAuthProvider from '../../../../models/saml-auth-provider.ee.js'; + +export default async (request, response) => { + const samlAuthProviders = await SamlAuthProvider.query().orderBy( + 'created_at', + 'desc' + ); + + renderObject(response, samlAuthProviders); +}; diff --git a/packages/backend/src/controllers/api/v1/saml-auth-providers/get-saml-auth-providers.ee.test.js b/packages/backend/src/controllers/api/v1/saml-auth-providers/get-saml-auth-providers.ee.test.js new file mode 100644 index 00000000..db6c716a --- /dev/null +++ b/packages/backend/src/controllers/api/v1/saml-auth-providers/get-saml-auth-providers.ee.test.js @@ -0,0 +1,46 @@ +import { vi, describe, it, expect, beforeEach } from 'vitest'; +import request from 'supertest'; +import app from '../../../../app.js'; +import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id.js'; +import { createUser } from '../../../../../test/factories/user.js'; +import { createPermission } from '../../../../../test/factories/permission.js'; +import { createSamlAuthProvider } from '../../../../../test/factories/saml-auth-provider.ee.js'; +import getSamlAuthProvidersMock from '../../../../../test/mocks/rest/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js'; +import * as license from '../../../../helpers/license.ee.js'; + +describe('GET /api/v1/saml-auth-providers', () => { + let samlAuthProviderOne, samlAuthProviderTwo, currentUser, token; + + beforeEach(async () => { + currentUser = await createUser(); + const role = await currentUser.$relatedQuery('role'); + + await createPermission({ + roleId: role.id, + action: 'read', + subject: 'SamlAuthProvider', + conditions: [], + }); + + samlAuthProviderOne = await createSamlAuthProvider(); + samlAuthProviderTwo = await createSamlAuthProvider(); + + token = createAuthTokenByUserId(currentUser.id); + }); + + it('should return saml auth providers', async () => { + vi.spyOn(license, 'hasValidLicense').mockResolvedValue(true); + + const response = await request(app) + .get('/api/v1/saml-auth-providers') + .set('Authorization', token) + .expect(200); + + const expectedPayload = await getSamlAuthProvidersMock([ + samlAuthProviderTwo, + samlAuthProviderOne, + ]); + + expect(response.body).toEqual(expectedPayload); + }); +}); diff --git a/packages/backend/src/helpers/authorization.js b/packages/backend/src/helpers/authorization.js index 28cefc59..28c3273e 100644 --- a/packages/backend/src/helpers/authorization.js +++ b/packages/backend/src/helpers/authorization.js @@ -7,6 +7,10 @@ const authorizationList = { action: 'read', subject: 'User', }, + '/api/v1/saml-auth-providers/': { + action: 'read', + subject: 'SamlAuthProvider', + }, }; export const authorizeUser = async (request, response, next) => { diff --git a/packages/backend/src/routes/api/v1/saml-auth-providers.ee.js b/packages/backend/src/routes/api/v1/saml-auth-providers.ee.js new file mode 100644 index 00000000..4f75beb2 --- /dev/null +++ b/packages/backend/src/routes/api/v1/saml-auth-providers.ee.js @@ -0,0 +1,17 @@ +import { Router } from 'express'; +import { authenticateUser } from '../../../helpers/authentication.js'; +import { authorizeUser } from '../../../helpers/authorization.js'; +import { checkIsEnterprise } from '../../../helpers/check-is-enterprise.js'; +import getSamlAuthProvidersAction from '../../../controllers/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js'; + +const router = Router(); + +router.get( + '/', + authenticateUser, + authorizeUser, + checkIsEnterprise, + getSamlAuthProvidersAction +); + +export default router; diff --git a/packages/backend/src/routes/index.js b/packages/backend/src/routes/index.js index 215a7326..144d9b28 100644 --- a/packages/backend/src/routes/index.js +++ b/packages/backend/src/routes/index.js @@ -5,6 +5,7 @@ import paddleRouter from './paddle.ee.js'; import healthcheckRouter from './healthcheck.js'; import automatischRouter from './api/v1/automatisch.js'; import usersRouter from './api/v1/users.js'; +import samlAuthProvidersRouter from './api/v1/saml-auth-providers.ee.js'; const router = Router(); @@ -14,5 +15,6 @@ router.use('/paddle', paddleRouter); router.use('/healthcheck', healthcheckRouter); router.use('/api/v1/automatisch', automatischRouter); router.use('/api/v1/users', usersRouter); +router.use('/api/v1/saml-auth-providers', samlAuthProvidersRouter); export default router; diff --git a/packages/backend/src/serializers/index.js b/packages/backend/src/serializers/index.js index fc4f257e..b8f30924 100644 --- a/packages/backend/src/serializers/index.js +++ b/packages/backend/src/serializers/index.js @@ -1,11 +1,13 @@ import userSerializer from './user.js'; import roleSerializer from './role.js'; import permissionSerializer from './permission.js'; +import samlAuthProviderSerializer from './saml-auth-provider.ee.js'; const serializers = { User: userSerializer, Role: roleSerializer, Permission: permissionSerializer, + SamlAuthProvider: samlAuthProviderSerializer, }; export default serializers; diff --git a/packages/backend/test/mocks/rest/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js b/packages/backend/test/mocks/rest/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js new file mode 100644 index 00000000..30d5bfc5 --- /dev/null +++ b/packages/backend/test/mocks/rest/api/v1/saml-auth-providers/get-saml-auth-providers.ee.js @@ -0,0 +1,31 @@ +const getSamlAuthProvidersMock = async (samlAuthProviders) => { + const data = samlAuthProviders.map((samlAuthProvider) => { + return { + active: samlAuthProvider.active, + certificate: samlAuthProvider.certificate, + defaultRoleId: samlAuthProvider.defaultRoleId, + emailAttributeName: samlAuthProvider.emailAttributeName, + entryPoint: samlAuthProvider.entryPoint, + firstnameAttributeName: samlAuthProvider.firstnameAttributeName, + id: samlAuthProvider.id, + issuer: samlAuthProvider.issuer, + name: samlAuthProvider.name, + roleAttributeName: samlAuthProvider.roleAttributeName, + signatureAlgorithm: samlAuthProvider.signatureAlgorithm, + surnameAttributeName: samlAuthProvider.surnameAttributeName, + }; + }); + + return { + data: data, + meta: { + count: data.length, + currentPage: null, + isArray: true, + totalPages: null, + type: 'SamlAuthProvider', + }, + }; +}; + +export default getSamlAuthProvidersMock;