Merge pull request #2234 from automatisch/saml-auth-provider-tests
SamlAuthProvider model tests
This commit is contained in:
@@ -149,34 +149,4 @@ describe('PATCH /api/v1/admin/saml-auth-providers/:samlAuthProviderId/role-mappi
|
|||||||
.send(roleMappings)
|
.send(roleMappings)
|
||||||
.expect(404);
|
.expect(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not delete existing role mapping when error thrown', async () => {
|
|
||||||
const roleMappings = [
|
|
||||||
{
|
|
||||||
roleId: userRole.id,
|
|
||||||
remoteRoleName: {
|
|
||||||
invalid: 'data',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const roleMappingsBeforeRequest = await samlAuthProvider.$relatedQuery(
|
|
||||||
'roleMappings'
|
|
||||||
);
|
|
||||||
|
|
||||||
await request(app)
|
|
||||||
.patch(
|
|
||||||
`/api/v1/admin/saml-auth-providers/${samlAuthProvider.id}/role-mappings`
|
|
||||||
)
|
|
||||||
.set('Authorization', token)
|
|
||||||
.send(roleMappings)
|
|
||||||
.expect(422);
|
|
||||||
|
|
||||||
const roleMappingsAfterRequest = await samlAuthProvider.$relatedQuery(
|
|
||||||
'roleMappings'
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(roleMappingsBeforeRequest).toStrictEqual(roleMappingsAfterRequest);
|
|
||||||
expect(roleMappingsAfterRequest.length).toBe(2);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
@@ -133,8 +133,7 @@ class SamlAuthProvider extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateRoleMappings(roleMappings) {
|
async updateRoleMappings(roleMappings) {
|
||||||
return await SamlAuthProvider.transaction(async (trx) => {
|
await this.$relatedQuery('roleMappings').delete();
|
||||||
await this.$relatedQuery('roleMappings', trx).delete();
|
|
||||||
|
|
||||||
if (isEmpty(roleMappings)) {
|
if (isEmpty(roleMappings)) {
|
||||||
return [];
|
return [];
|
||||||
@@ -145,12 +144,11 @@ class SamlAuthProvider extends Base {
|
|||||||
samlAuthProviderId: this.id,
|
samlAuthProviderId: this.id,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const newRoleMappings = await RoleMapping.query(trx).insertAndFetch(
|
const newRoleMappings = await RoleMapping.query().insertAndFetch(
|
||||||
roleMappingsData
|
roleMappingsData
|
||||||
);
|
);
|
||||||
|
|
||||||
return newRoleMappings;
|
return newRoleMappings;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,14 @@
|
|||||||
import { vi, describe, it, expect } from 'vitest';
|
import { vi, beforeEach, describe, it, expect } from 'vitest';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import SamlAuthProvider from '../models/saml-auth-provider.ee';
|
import SamlAuthProvider from '../models/saml-auth-provider.ee';
|
||||||
import RoleMapping from '../models/role-mapping.ee';
|
import RoleMapping from '../models/role-mapping.ee';
|
||||||
|
import axios from '../helpers/axios-with-proxy.js';
|
||||||
import Identity from './identity.ee';
|
import Identity from './identity.ee';
|
||||||
import Base from './base';
|
import Base from './base';
|
||||||
import appConfig from '../config/app';
|
import appConfig from '../config/app';
|
||||||
|
import { createSamlAuthProvider } from '../../test/factories/saml-auth-provider.ee.js';
|
||||||
|
import { createRoleMapping } from '../../test/factories/role-mapping.js';
|
||||||
|
import { createRole } from '../../test/factories/role.js';
|
||||||
|
|
||||||
describe('SamlAuthProvider model', () => {
|
describe('SamlAuthProvider model', () => {
|
||||||
it('tableName should return correct name', () => {
|
it('tableName should return correct name', () => {
|
||||||
@@ -81,4 +86,146 @@ describe('SamlAuthProvider model', () => {
|
|||||||
'https://example.com/saml/logout'
|
'https://example.com/saml/logout'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('config should return the correct configuration object', () => {
|
||||||
|
const samlAuthProvider = new SamlAuthProvider();
|
||||||
|
|
||||||
|
samlAuthProvider.certificate = 'sample-certificate';
|
||||||
|
samlAuthProvider.signatureAlgorithm = 'sha256';
|
||||||
|
samlAuthProvider.entryPoint = 'https://example.com/saml';
|
||||||
|
samlAuthProvider.issuer = 'sample-issuer';
|
||||||
|
|
||||||
|
vi.spyOn(appConfig, 'baseUrl', 'get').mockReturnValue(
|
||||||
|
'https://automatisch.io'
|
||||||
|
);
|
||||||
|
|
||||||
|
const expectedConfig = {
|
||||||
|
callbackUrl: 'https://automatisch.io/login/saml/sample-issuer/callback',
|
||||||
|
cert: 'sample-certificate',
|
||||||
|
entryPoint: 'https://example.com/saml',
|
||||||
|
issuer: 'sample-issuer',
|
||||||
|
signatureAlgorithm: 'sha256',
|
||||||
|
logoutUrl: 'https://example.com/saml',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(samlAuthProvider.config).toStrictEqual(expectedConfig);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('generateLogoutRequestBody should return a correctly encoded SAML logout request', () => {
|
||||||
|
vi.mock('uuid', () => ({
|
||||||
|
v4: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const samlAuthProvider = new SamlAuthProvider();
|
||||||
|
|
||||||
|
samlAuthProvider.entryPoint = 'https://example.com/saml';
|
||||||
|
samlAuthProvider.issuer = 'sample-issuer';
|
||||||
|
|
||||||
|
const mockUuid = '123e4567-e89b-12d3-a456-426614174000';
|
||||||
|
uuidv4.mockReturnValue(mockUuid);
|
||||||
|
|
||||||
|
const sessionId = 'test-session-id';
|
||||||
|
|
||||||
|
const logoutRequest = samlAuthProvider.generateLogoutRequestBody(sessionId);
|
||||||
|
|
||||||
|
const expectedLogoutRequest = `
|
||||||
|
<samlp:LogoutRequest
|
||||||
|
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
|
||||||
|
ID="${mockUuid}"
|
||||||
|
Version="2.0"
|
||||||
|
IssueInstant="${new Date().toISOString()}"
|
||||||
|
Destination="https://example.com/saml">
|
||||||
|
|
||||||
|
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">sample-issuer</saml:Issuer>
|
||||||
|
<samlp:SessionIndex>test-session-id</samlp:SessionIndex>
|
||||||
|
</samlp:LogoutRequest>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const expectedEncodedRequest = Buffer.from(expectedLogoutRequest).toString(
|
||||||
|
'base64'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(logoutRequest).toBe(expectedEncodedRequest);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('terminateRemoteSession should send the correct POST request and return the response', async () => {
|
||||||
|
vi.mock('../helpers/axios-with-proxy.js', () => ({
|
||||||
|
default: {
|
||||||
|
post: vi.fn(),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const samlAuthProvider = new SamlAuthProvider();
|
||||||
|
|
||||||
|
samlAuthProvider.entryPoint = 'https://example.com/saml';
|
||||||
|
samlAuthProvider.generateLogoutRequestBody = vi
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue('mockEncodedLogoutRequest');
|
||||||
|
|
||||||
|
const sessionId = 'test-session-id';
|
||||||
|
|
||||||
|
const mockResponse = { data: 'Logout Successful' };
|
||||||
|
axios.post.mockResolvedValue(mockResponse);
|
||||||
|
|
||||||
|
const response = await samlAuthProvider.terminateRemoteSession(sessionId);
|
||||||
|
|
||||||
|
expect(samlAuthProvider.generateLogoutRequestBody).toHaveBeenCalledWith(
|
||||||
|
sessionId
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(axios.post).toHaveBeenCalledWith(
|
||||||
|
'https://example.com/saml',
|
||||||
|
'SAMLRequest=mockEncodedLogoutRequest',
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(response).toBe(mockResponse);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateRoleMappings', () => {
|
||||||
|
let samlAuthProvider;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
samlAuthProvider = await createSamlAuthProvider();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove all existing role mappings', async () => {
|
||||||
|
await createRoleMapping({
|
||||||
|
samlAuthProviderId: samlAuthProvider.id,
|
||||||
|
remoteRoleName: 'Admin',
|
||||||
|
});
|
||||||
|
|
||||||
|
await createRoleMapping({
|
||||||
|
samlAuthProviderId: samlAuthProvider.id,
|
||||||
|
remoteRoleName: 'User',
|
||||||
|
});
|
||||||
|
|
||||||
|
await samlAuthProvider.updateRoleMappings([]);
|
||||||
|
|
||||||
|
const roleMappings = await samlAuthProvider.$relatedQuery('roleMappings');
|
||||||
|
expect(roleMappings).toStrictEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the updated role mappings when new ones are provided', async () => {
|
||||||
|
const adminRole = await createRole({ name: 'Admin' });
|
||||||
|
const userRole = await createRole({ name: 'User' });
|
||||||
|
|
||||||
|
const newRoleMappings = [
|
||||||
|
{ remoteRoleName: 'Admin', roleId: adminRole.id },
|
||||||
|
{ remoteRoleName: 'User', roleId: userRole.id },
|
||||||
|
];
|
||||||
|
|
||||||
|
const result = await samlAuthProvider.updateRoleMappings(newRoleMappings);
|
||||||
|
|
||||||
|
const refetchedRoleMappings = await samlAuthProvider.$relatedQuery(
|
||||||
|
'roleMappings'
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result).toStrictEqual(refetchedRoleMappings);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user