Skip to content

Commit

Permalink
feat: Canner PAT authenticator
Browse files Browse the repository at this point in the history
 - add Canner PAT authenticator
 - add unit tests
 - add integration tests
  • Loading branch information
onlyjackfrost committed Jun 5, 2023
1 parent 2b5e282 commit 7420552
Show file tree
Hide file tree
Showing 6 changed files with 615 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ import { IBuildOptions, VulcanBuilder } from '@vulcan-sql/build';
import { ServeConfig, VulcanServer } from '@vulcan-sql/serve';
import * as supertest from 'supertest';
import * as md5 from 'md5';
import * as sinon from 'ts-sinon';
import defaultConfig from './projectConfig';
import faker from '@faker-js/faker';

let server: VulcanServer;

// clear stub after each test
afterEach(() => {
sinon.default.restore();
});

const users = [
{
name: 'william',
Expand All @@ -23,29 +30,6 @@ const users = [
},
];

const projectConfig: ServeConfig & IBuildOptions = {
...defaultConfig,
auth: {
enabled: true,
options: {
basic: {
'users-list': [
{
name: users[0].name,
md5Password: md5(users[0].password),
attr: users[0].attr,
},
{
name: users[1].name,
md5Password: md5(users[1].password),
attr: users[1].attr,
},
],
},
},
},
};

afterEach(async () => {
await server.close();
});
Expand All @@ -54,6 +38,28 @@ it.each([...users])(
'Example 2: authenticate user identity by POST /auth/token API',
async ({ name, password }) => {
// Arrange
const projectConfig: ServeConfig & IBuildOptions = {
...defaultConfig,
auth: {
enabled: true,
options: {
basic: {
'users-list': [
{
name: users[0].name,
md5Password: md5(users[0].password),
attr: users[0].attr,
},
{
name: users[1].name,
md5Password: md5(users[1].password),
attr: users[1].attr,
},
],
},
},
},
};
const expected = Buffer.from(`${name}:${password}`).toString('base64');
const builder = new VulcanBuilder(projectConfig);
await builder.build();
Expand All @@ -76,3 +82,39 @@ it.each([...users])(
},
10000
);

it('Example 2: authenticate user identity by POST /auth/token API using PAT should get 400', async () => {
// Arrange
const projectConfig: ServeConfig & IBuildOptions = {
...defaultConfig,
auth: {
enabled: true,
options: {
'canner-pat': {
host: 'mockhost',
port: faker.datatype.number({ min: 20000, max: 30000 }),
ssl: false,
},
},
},
};
const builder = new VulcanBuilder(projectConfig);
await builder.build();
server = new VulcanServer(projectConfig);
const httpServer = (await server.start())['http'];
// Act
const agent = supertest(httpServer);

// Assert
const result = await agent
.post('/auth/token')
.send({
type: 'canner-pat',
})
.set('Accept', 'application/json')
.set('Authorization', 'Canner-PAT mocktoken');
expect(result.status).toBe(400);
expect(JSON.parse(result.text).message).toBe(
'canner-pat does not support token generate.'
);
}, 10000);
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { IBuildOptions, VulcanBuilder } from '@vulcan-sql/build';
import {
ServeConfig,
VulcanServer,
CannerPATAuthenticator,
} from '@vulcan-sql/serve';
import * as supertest from 'supertest';
import defaultConfig from './projectConfig';
import * as sinon from 'ts-sinon';

describe('Example3: get user profile by GET /auth/user-profile API with Authorization', () => {
let server: VulcanServer;
let projectConfig: ServeConfig & IBuildOptions;
const mockUser = {
username: 'apple Hey',
firstName: 'Hey',
lastName: 'apple',
accountRole: 'admin',

attributes: {
attr1: 100 * 10000,
attr2: 'Los Angeles',
},
createdAt: '2023-03-27T12:48:15.882Z',
email: 'Alvina_Farrell82@yahoo.com',
groups: [{ id: 1, name: 'group1' }],
};
const mockToken = `Canner-PAT myPATToken`;
const mockCannerUserResponse = {
status: 200,
data: {
data: {
userMe: mockUser,
},
},
};
const expectedUserProfile = {
name: mockUser.username,
attr: {
firstName: 'Hey',
lastName: 'apple',
accountRole: 'admin',

attributes: {
attr1: 100 * 10000,
attr2: 'Los Angeles',
},
createdAt: '2023-03-27T12:48:15.882Z',
email: 'Alvina_Farrell82@yahoo.com',
groups: [{ id: 1, name: 'group1' }],
},
};
// stub fetchCannerUser method in class CannerPATAuthenticator using sinon
const stubFetchCannerUser = (user: any) => {
const stub = sinon.default.stub(
CannerPATAuthenticator.prototype,
<any>'fetchCannerUser'
);
stub.resolves(user);
return stub;
};
beforeEach(async () => {
projectConfig = {
...defaultConfig,
auth: {
enabled: true,
options: {
'canner-pat': {
host: 'mockhost',
port: 3000,
ssl: false,
},
},
},
};
});

afterEach(async () => {
sinon.default.restore();
await server?.close();
});

it('Example 3-1: set Authorization in header with default options', async () => {
stubFetchCannerUser(mockCannerUserResponse);
const builder = new VulcanBuilder(projectConfig);
await builder.build();
server = new VulcanServer(projectConfig);
const httpServer = (await server.start())['http'];

const agent = supertest(httpServer);
const result = await agent
.get('/auth/user-profile')
.set('Authorization', mockToken);
expect(result.body).toEqual(expectedUserProfile);
}, 10000);

it('Example 3-2: set Authorization in querying with default options', async () => {
projectConfig['auth-source'] = {
options: {
key: 'x-auth',
},
};
stubFetchCannerUser(mockCannerUserResponse);
const builder = new VulcanBuilder(projectConfig);
await builder.build();
server = new VulcanServer(projectConfig);
const httpServer = (await server.start())['http'];

const agent = supertest(httpServer);
const auth = Buffer.from(
JSON.stringify({
Authorization: `Canner-PAT ${Buffer.from(mockToken).toString(
'base64'
)}`,
})
).toString('base64');
const result = await agent.get(`/auth/user-profile?x-auth=${auth}`);

expect(result.body).toEqual(expectedUserProfile);
}, 10000);

it('Example 3-3: set Authorization in querying with specific auth "key" options', async () => {
projectConfig['auth-source'] = {
options: {
key: 'x-auth',
},
};
stubFetchCannerUser(mockCannerUserResponse);
const builder = new VulcanBuilder(projectConfig);
await builder.build();
server = new VulcanServer(projectConfig);
const httpServer = (await server.start())['http'];

const agent = supertest(httpServer);
const auth = Buffer.from(
JSON.stringify({
Authorization: `Canner-PAT ${Buffer.from(mockToken).toString(
'base64'
)}`,
})
).toString('base64');
const result = await agent.get(`/auth/user-profile?x-auth=${auth}`);

expect(result.body).toEqual(expectedUserProfile);
}, 10000);

it('Example 3-4: set Authorization in json payload specific auth "x-key" options', async () => {
projectConfig['auth-source'] = {
options: {
key: 'x-auth',
in: 'payload',
},
};
stubFetchCannerUser(mockCannerUserResponse);
const builder = new VulcanBuilder(projectConfig);
await builder.build();
server = new VulcanServer(projectConfig);
const httpServer = (await server.start())['http'];

const auth = Buffer.from(
JSON.stringify({
Authorization: `Canner-PAT ${Buffer.from(mockToken).toString(
'base64'
)}`,
})
).toString('base64');

const agent = supertest(httpServer);

const result = await agent
.get('/auth/user-profile')
.send({
['x-auth']: auth,
})
.set('Accept', 'application/json');

expect(result.body).toEqual(expectedUserProfile);
}, 10000);
});
Loading

0 comments on commit 7420552

Please sign in to comment.