Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: save synapse token in memory instead of mongoDB #320

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
98971c2
fix: removed synapse createRoom and createUser services
Junjiequan Jun 22, 2023
075eed3
fix: remove createRoom and createUser service
Junjiequan Jun 22, 2023
4e3f998
ignore: format reset
Junjiequan Jun 22, 2023
8f1ebed
fix: removed rabbit-mq observer
Junjiequan Jun 22, 2023
e244cd5
TODO: 2 todos included.
Junjiequan Jun 22, 2023
f8ee7f1
fix: removed unnecessary files & saving token in memory
Junjiequan Jul 19, 2023
719392c
fix: minor cleanup
Junjiequan Sep 7, 2023
d36c149
test
Junjiequan Sep 7, 2023
74cc824
test2
Junjiequan Sep 7, 2023
746d987
test3
Junjiequan Sep 7, 2023
baa6bcc
fix: added endpoint to check whether token should be renewed
Junjiequan Sep 7, 2023
933b106
fix: test fail fix
Junjiequan Sep 8, 2023
01a3f54
fix: test fix
Junjiequan Sep 8, 2023
7373a1f
test
Junjiequan Sep 8, 2023
f93a87e
test
Junjiequan Sep 8, 2023
d416492
test
Junjiequan Sep 8, 2023
6982e36
test
Junjiequan Sep 8, 2023
fa251fd
test
Junjiequan Sep 10, 2023
0b3e923
test
Junjiequan Sep 10, 2023
4058dfe
test2
Junjiequan Sep 10, 2023
fb2d055
test
Junjiequan Sep 10, 2023
5c340d6
test
Junjiequan Sep 10, 2023
848e08e
test - synapse.service.ts
Junjiequan Sep 10, 2023
d2f907a
test2
Junjiequan Sep 10, 2023
f16a933
test
Junjiequan Sep 10, 2023
98ff92c
testing - test pass
Junjiequan Sep 10, 2023
49ac4fd
fix: removed acceptance testing
Junjiequan Sep 12, 2023
12b6f3e
fix: removed mongoDB, updated ReadMe and cleaned up ENV files
Junjiequan Sep 20, 2023
b2d736c
fix: test fail fix
Junjiequan Sep 20, 2023
d2c9adb
fix: test fix
Junjiequan Sep 20, 2023
0666411
fix: home-page acceptance fix
Junjiequan Sep 20, 2023
ac0be9d
fix: remove env from github job
Junjiequan Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions src/__tests__/acceptance/logbook.controller.acceptance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Client } from "@loopback/testlab";
import { Client, expect } from "@loopback/testlab";
import { ScichatLoopbackApplication } from "../../application";
import { setupApplication } from "./test-helper";

Expand All @@ -16,25 +16,31 @@ describe("LogbookController (acceptance)", () => {

context("find", () => {
it("should resolve in a 401 code with unauthenticated user", async () => {
await client.get("/scichatapi/Logbooks").expect(401);
});
});

context("create", () => {
it("should resolve in a 401 code with unauthenticated user", async () => {
await client.post("/scichatapi/Logbooks").expect(401);
try {
await client.get("/scichatapi/Logbooks");
} catch (error) {
expect(error.statusCode).equal(401);
}
});
});

context("findByName", () => {
it("should resolve in a 401 code with unauthenticated user", async () => {
await client.get("/scichatapi/Logbooks/123456").expect(401);
try {
await client.get("/scichatapi/Logbooks/123456");
} catch (error) {
expect(error.statusCode).equal(401);
}
});
});

context("sendMessage", () => {
it("should resolve in a 401 code with unauthenticated user", async () => {
await client.post("/scichatapi/Logbooks/123456/message").expect(401);
try {
await client.post("/scichatapi/Logbooks/123456/message");
} catch (error) {
expect(error.statusCode).equal(401);
}
});
});
});
3 changes: 0 additions & 3 deletions src/__tests__/acceptance/test-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
givenHttpServerConfig,
} from "@loopback/testlab";
import { ScichatLoopbackApplication } from "../..";
import { testdbConfig } from "../fixtures/datasources/testdb.datasource";

export async function setupApplication(): Promise<AppWithClient> {
const restConfig = givenHttpServerConfig({
Expand All @@ -21,8 +20,6 @@ export async function setupApplication(): Promise<AppWithClient> {

await app.boot();

app.bind("datasources.config.mongodb").to(testdbConfig);

await app.start();

const client = createRestAppClient(app);
Expand Down
20 changes: 1 addition & 19 deletions src/__tests__/acceptance/user.controller.acceptance.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { Client, expect } from "@loopback/testlab";
import { Client } from "@loopback/testlab";
import { ScichatLoopbackApplication } from "../../application";
import {
givenCredentials,
givenEmptyDatabase,
givenUserAccount,
} from "../helpers";
import { setupApplication } from "./test-helper";

describe("UserController (acceptance)", () => {
Expand All @@ -15,9 +10,6 @@ describe("UserController (acceptance)", () => {
({ app, client } = await setupApplication());
});

before(givenEmptyDatabase);
before(givenUserAccount);

after(() => app.stop());

context("login", () => {
Expand All @@ -28,15 +20,5 @@ describe("UserController (acceptance)", () => {
.send(credentials)
.expect(401);
});

it("should resolve in a jwt token when logging in with the correct credentials", async () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question. Why was this test removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After refactoring JWT validation is no longer needed so is for the JWT test.
Within this PR synapse credential will be directly passed to loopback from SciCat BE, then loopback will use the credential to login Synapse server and save generated token in the memory.

const credentials = givenCredentials();
const res = await client
.post("/scichatapi/Users/login")
.send(credentials)
.expect(200);

expect(res.body).to.have.property("token");
});
});
});
10 changes: 0 additions & 10 deletions src/__tests__/fixtures/datasources/testdb.datasource.ts

This file was deleted.

52 changes: 1 addition & 51 deletions src/__tests__/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,5 @@
import { genSalt, hash } from "bcryptjs";
import { MongodbDataSource } from "../datasources";
import { Logbook, SynapseToken, User, UserCredentials } from "../models";
import { UserCredentialsRepository, UserRepository } from "../repositories";
import { Logbook, SynapseToken } from "../models";
import { SynapseSyncResponse } from "../services";
import { testdbConfig } from "./fixtures/datasources/testdb.datasource";

const testdb = new MongodbDataSource(testdbConfig);
const userRepository = new UserRepository(
testdb,
async () => userCredentialsRepository,
);
const userCredentialsRepository = new UserCredentialsRepository(testdb);

export async function givenEmptyDatabase() {
await userRepository.deleteAll();
await userCredentialsRepository.deleteAll();
}

export function givenUserData(data?: Partial<User>) {
return Object.assign(
{
username: "testUser",
email: "[email protected]",
},
data,
);
}

export async function givenUser(data?: Partial<User>) {
return userRepository.create(givenUserData(data));
}

export async function givenUserCredentialsData(
data?: Partial<UserCredentials>,
) {
return Object.assign(
{
password: await hash("password", await genSalt()),
},
data,
);
}

export async function givenUserCredentials(data?: Partial<UserCredentials>) {
return userCredentialsRepository.create(await givenUserCredentialsData(data));
}

export async function givenUserAccount() {
const user = await givenUser();
return givenUserCredentials({ userId: user.id });
}

export function givenCredentials() {
return { username: "testUser", password: "password" };
Expand Down
47 changes: 14 additions & 33 deletions src/__tests__/unit/logbook.controller.unit.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import {
createStubInstance,
expect,
StubbedInstanceWithSinonAccessor,
} from "@loopback/testlab";
import { Context } from "@loopback/context";
import { expect } from "@loopback/testlab";
import sinon from "sinon";
import { LogbookController } from "../../controllers";
import { SynapseTokenRepository } from "../../repositories";
import { SynapseService } from "../../services";
import { TokenServiceManager } from "../../services/token.service";
import { Utils } from "../../utils";
import {
givenAllRoomsSyncResponse,
givenCreateRoomResponse,
givenFetchRoomIdByNameResponse,
givenFetchRoomMessagesResponse,
givenGetMessagesWithDisplayNameResponse,
Expand All @@ -22,21 +18,19 @@ import {
describe("LogbookController (unit)", () => {
let controller: LogbookController;

let synapseTokenRepositry: StubbedInstanceWithSinonAccessor<SynapseTokenRepository>;
let synapseService: SynapseService;
let tokenServiceManager: TokenServiceManager;
let utils: Utils;
let createRoom: sinon.SinonStub;
let fetchAllRoomsMessages: sinon.SinonStub;
let fetchRoomIdByName: sinon.SinonStub;
let fetchRoomMessages: sinon.SinonStub;
let getMessagesWithDisplayName: sinon.SinonStub;
let sendMessage: sinon.SinonStub;

beforeEach(givenMockSynapseServiceAndRepository);
beforeEach(givenMockSynapseServiceAndTokenManager);

context("find", () => {
it("resolves a list of Logbooks", async () => {
synapseTokenRepositry.stubs.findOne.resolves(givenSynapseLoginResponse());
fetchAllRoomsMessages.resolves(givenAllRoomsSyncResponse());

const expected = givenLogbooks();
Expand All @@ -45,22 +39,8 @@ describe("LogbookController (unit)", () => {
});
});

context("create", () => {
it("resolves in an object containing the room_alias and room_id", async () => {
const details = { name: "098765" };
synapseTokenRepositry.stubs.findOne.resolves(givenSynapseLoginResponse());
createRoom.resolves(givenCreateRoomResponse(details));

const expected = givenCreateRoomResponse(details);
const actual = await controller.create(details);

expect(actual).to.eql(expected);
});
});

context("findByName", () => {
it("resolves in a Logbook instance matching the input name", async () => {
synapseTokenRepositry.stubs.findOne.resolves(givenSynapseLoginResponse());
fetchRoomIdByName.resolves(givenFetchRoomIdByNameResponse());
fetchRoomMessages.resolves(givenFetchRoomMessagesResponse());
getMessagesWithDisplayName.resolves(
Expand All @@ -75,7 +55,6 @@ describe("LogbookController (unit)", () => {
context("sendMessage", () => {
it("resolves in an object containing the event_id of the sent message", async () => {
const expected = { event_id: "$ABCDabcd1234" };
synapseTokenRepositry.stubs.findOne.resolves(givenSynapseLoginResponse());
fetchRoomIdByName.resolves(givenFetchRoomIdByNameResponse());
sendMessage.resolves(expected);

Expand All @@ -86,29 +65,31 @@ describe("LogbookController (unit)", () => {
});
});

function givenMockSynapseServiceAndRepository() {
function givenMockSynapseServiceAndTokenManager() {
synapseService = {
login: sinon.stub(),
createRoom: sinon.stub(),
fetchAllRoomsMessages: sinon.stub(),
fetchRoomIdByName: sinon.stub(),
fetchRoomMessages: sinon.stub(),
sendMessage: sinon.stub(),
queryUser: sinon.stub(),
createUser: sinon.stub(),
};

createRoom = synapseService.createRoom as sinon.SinonStub;
tokenServiceManager = new TokenServiceManager(new Context());

fetchAllRoomsMessages =
synapseService.fetchAllRoomsMessages as sinon.SinonStub;
fetchRoomIdByName = synapseService.fetchRoomIdByName as sinon.SinonStub;
fetchRoomMessages = synapseService.fetchRoomMessages as sinon.SinonStub;
sendMessage = synapseService.sendMessage as sinon.SinonStub;

synapseTokenRepositry = createStubInstance(SynapseTokenRepository);
utils = new Utils(synapseTokenRepositry, synapseService);
tokenServiceManager.getToken = sinon
.stub()
.returns(givenSynapseLoginResponse().access_token);

utils = new Utils(tokenServiceManager, synapseService);
controller = new LogbookController(
synapseTokenRepositry,
tokenServiceManager,
synapseService,
utils,
);
Expand Down
20 changes: 12 additions & 8 deletions src/application.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AuthenticationComponent } from "@loopback/authentication";
import { BootMixin } from "@loopback/boot";
import { ApplicationConfig } from "@loopback/core";
import { ApplicationConfig, BindingScope } from "@loopback/core";
import { RepositoryMixin } from "@loopback/repository";
import { RestApplication } from "@loopback/rest";
import {
Expand All @@ -9,10 +9,9 @@ import {
} from "@loopback/rest-explorer";
import { ServiceMixin } from "@loopback/service-proxy";
import path from "path";
import { MongodbDataSource } from "./datasources";
import { JWTAuthenticationComponent } from "./jwt-authentication-component";
import { UserServiceBindings, UtilsBindings } from "./keys";
import { TokenServiceBindings, UtilsBindings } from "./keys";
import { MySequence } from "./sequence";
import { TokenServiceManager } from "./services/token.service";
import { Utils } from "./utils";

export { ApplicationConfig };
Expand Down Expand Up @@ -48,11 +47,16 @@ export class ScichatLoopbackApplication extends BootMixin(

// Mount authentication system
this.component(AuthenticationComponent);
// Mount jwt component
this.component(JWTAuthenticationComponent);
// Bind datasource
this.dataSource(MongodbDataSource, UserServiceBindings.DATASOURCE_NAME);

this.bind(UtilsBindings.UTILS).toClass(Utils);

this.bind(TokenServiceBindings.TOKEN_MANAGER)
.toClass(TokenServiceManager)
//
.inScope(BindingScope.SINGLETON);

this.bind(TokenServiceBindings.TOKEN_KEY)
.to("")
.inScope(BindingScope.SINGLETON);
}
}
Loading