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

Promote from BLAIS5-4525 to main #390

Merged
merged 19 commits into from
Jan 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 7 additions & 11 deletions server/routes/blaiseApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,6 @@ export default function blaiseApi(config: CustomConfig, auth: Auth, blaiseApiCli
});

router.get("/api/users/:user", auth.Middleware, async function (req: Request, res: Response) {
if (!req.params.user) {
return res.status(400).json("No user provided");
}

try {
const user = await blaiseApiClient.getUser(req.params.user);
const successMessage = `Successfully fetched user details for ${req.params.user}`;
Expand All @@ -75,19 +71,19 @@ export default function blaiseApi(config: CustomConfig, auth: Auth, blaiseApiCli
}
});

router.get("/api/change-password/:user", auth.Middleware, async function (req: Request, res: Response) {
router.post("/api/change-password/:user", auth.Middleware, async function (req: Request, res: Response) {
const currentUser = auth.GetUser(auth.GetToken(req));
let { password } = req.headers;
const data = req.body;

if (Array.isArray(password)) {
password = password.join("");
if (Array.isArray(data.password)) {
data.password = data.password.join("");
}

if (!req.params.user || !password) {
if (!req.params.user || !data.password) {
return res.status(400).json("No user or password provided");
}

blaiseApiClient.changePassword(req.params.user, password).then(() => {
blaiseApiClient.changePassword(req.params.user, data.password).then(() => {
auditLogger.info(req.log, `${currentUser.name || "Unknown"} has successfully changed the password for ${req.params.user}`);
return res.status(204).json(null);
}).catch((error: unknown) => {
Expand Down Expand Up @@ -123,7 +119,7 @@ export default function blaiseApi(config: CustomConfig, auth: Auth, blaiseApiCli
const currentUser = auth.GetUser(auth.GetToken(req));
const data = req.body;

if(!data.role) {
if (!data.role) {
return res.status(400).json({ message: "No role provided for user creation" });
}

Expand Down
118 changes: 90 additions & 28 deletions server/tests/routes/blaiseApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,14 @@ describe("POST /api/users endpoint", () => {
it("should call Blaise API createUser endpoint with correct serverParks for each role EXISTING in server/role-to-serverparks-map.json AND return http status OK_200", async () => {
let currentRoleNo = 0;
const totalRoleCount = size(role_to_serverparks_map);
for (const roleName in role_to_serverparks_map)
{
for (const roleName in role_to_serverparks_map) {
logInfo.mockReset();
blaiseApiMock.reset();
console.log("Running for role %i of %i: %s", ++currentRoleNo, totalRoleCount, roleName);

const spmap = role_to_serverparks_map[roleName];
const newUser : NewUser = {
name: "name1",
const newUser: NewUser = {
name: "name1",
password: "password1",
role: roleName,
serverParks: spmap,
Expand All @@ -78,7 +77,7 @@ describe("POST /api/users endpoint", () => {
expect(logInfo.mock.calls[0][0]).toEqual(`AUDIT_LOG: ${mockUser.name} has successfully created user, ${newUser.name}, with an assigned role of ${roleName}`);
expect(response.statusCode).toEqual(200);
blaiseApiMock.verify(a => a.createUser(It.is<NewUser>(
x=> x.defaultServerPark == newUser.defaultServerPark
x => x.defaultServerPark == newUser.defaultServerPark
&& x.role == newUser.role
&& Array.isArray(x.serverParks) && x.serverParks.every(item => typeof item === "string")
&& x.serverParks.every((val, idx) => val === newUser.serverParks[idx])
Expand All @@ -90,8 +89,8 @@ describe("POST /api/users endpoint", () => {
it("should call Blaise API createUser endpoint with DEFAULT serverParks for a role MISSING in server/role-to-serverparks-map.json AND return http status OK_200)", async () => {
const roleName = "this role is missing in server/role-to-serverparks-map.json file";
const spmap = role_to_serverparks_map.DEFAULT;
const newUser : NewUser = {
name: "name1",
const newUser: NewUser = {
name: "name1",
password: "password1",
role: roleName,
serverParks: spmap,
Expand All @@ -108,7 +107,7 @@ describe("POST /api/users endpoint", () => {
expect(log).toEqual(`AUDIT_LOG: ${mockUser.name} has successfully created user, ${newUser.name}, with an assigned role of ${roleName}`);
expect(response.statusCode).toEqual(200);
blaiseApiMock.verify(a => a.createUser(It.is<NewUser>(
x=> x.defaultServerPark == newUser.defaultServerPark
x => x.defaultServerPark == newUser.defaultServerPark
&& x.role == newUser.role
&& Array.isArray(x.serverParks) && x.serverParks.every(item => typeof item === "string")
&& x.serverParks.every((val, idx) => val === newUser.serverParks[idx])
Expand All @@ -133,8 +132,8 @@ describe("POST /api/users endpoint", () => {
it("should return http status INTERNAL_SERVER_ERROR_500 if Blaise API client throws an error", async () => {
const roleName = "IPS Manager";
const spmap = role_to_serverparks_map.DEFAULT;
const newUser : NewUser = {
name: "name1",
const newUser: NewUser = {
name: "name1",
password: "password1",
role: roleName,
serverParks: spmap,
Expand Down Expand Up @@ -215,8 +214,8 @@ describe("GET /api/users endpoint", () => {
});

it("should call Blaise API getUsers endpoint AND return http status OK_200", async () => {
const newUser1 : NewUser = {
name: "name1",
const newUser1: NewUser = {
name: "name1",
password: "password1",
role: "role1",
serverParks: ["sp1", "sp2"],
Expand All @@ -226,7 +225,7 @@ describe("GET /api/users endpoint", () => {
newUser2.name = "name2";
const newUser3 = newUser2;
newUser3.name = "name3";
const userArray : NewUser [] = [newUser1, newUser2, newUser3];
const userArray: NewUser[] = [newUser1, newUser2, newUser3];
blaiseApiMock.setup((api) => api.getUsers()).returns(_ => Promise.resolve(userArray));

const response = await sut.get("/api/users")
Expand All @@ -243,16 +242,16 @@ describe("GET /api/roles endpoint", () => {
});

it("should call Blaise API getUserRoles endpoint AND return http status OK_200", async () => {
const userRole1 : UserRole = {
name: "name1",
const userRole1: UserRole = {
name: "name1",
description: "desc1",
permissions: ["perm1", "perm2"]
};
const userRole2 = userRole1;
userRole2.name = "name2";
const userRole3 = userRole2;
userRole3.name = "name3";
const userRoleArray : UserRole [] = [userRole1, userRole2, userRole3];
const userRoleArray: UserRole[] = [userRole1, userRole2, userRole3];
blaiseApiMock.setup((api) => api.getUserRoles()).returns(_ => Promise.resolve(userRoleArray));

const response = await sut.get("/api/roles")
Expand All @@ -263,24 +262,22 @@ describe("GET /api/roles endpoint", () => {
});
});

describe("GET /api/change-password/:user endpoint", () => {
describe("POST /api/change-password/:user endpoint", () => {
beforeEach(() => {
blaiseApiMock.reset();
jest.clearAllMocks();
});

afterAll(() => {
blaiseApiMock.reset();
});

it("should call Blaise API changePassword endpoint for VALID request AND return http status NO_CONTENT_204", async () => {
const username = "user1";
const password = "password-1234";
blaiseApiMock.setup((api) => api.changePassword(It.isAnyString(), It.isAnyString())).returns(_ => Promise.resolve(null));

const response = await sut.get("/api/change-password/"+username)
const response = await sut.post(`/api/change-password/${username}`)
.set("Authorization", `${mockAuthToken}`)
.set("password", password);
.field("password", password);

const log = logInfo.mock.calls[0][0];
expect(log).toEqual(`AUDIT_LOG: ${mockUser.name} has successfully changed the password for ${username}`);
Expand All @@ -292,9 +289,9 @@ describe("GET /api/change-password/:user endpoint", () => {
const username = "user1";
const password = "";

const response = await sut.get("/api/change-password/"+ username)
const response = await sut.post(`/api/change-password/${username}`)
.set("Authorization", `${mockAuthToken}`)
.set("password", password);
.field("password", password);

expect(response.statusCode).toEqual(400);
blaiseApiMock.verify(a => a.changePassword(It.isAnyString(), It.isAnyString()), Times.never());
Expand All @@ -304,19 +301,42 @@ describe("GET /api/change-password/:user endpoint", () => {
const username = "user1";
const password = "password-1234";
const errorMessage = "Error occured when calling changePassword on Blaise API Rest Service";
blaiseApiMock.setup((a) => a.changePassword(It.isAnyString(), It.isAnyString()))
.returns(_ => Promise.reject(errorMessage));
blaiseApiMock.setup((api) => api.changePassword(It.isAnyString(), It.isAnyString())).returns(_ => Promise.reject(errorMessage));

const response = await sut.get("/api/change-password/"+ username)
const response = await sut.post(`/api/change-password/${username}`)
.set("Authorization", `${mockAuthToken}`)
.set("password", password);
.field("password", password);

const log = logError.mock.calls[0][0];
expect(log).toEqual(`AUDIT_LOG: Error whilst trying to change password for ${username}: ${errorMessage}`);
expect(response.statusCode).toEqual(500);
blaiseApiMock.verify(a => a.changePassword(It.isAnyString(), It.isAnyString()), Times.once());
expect(response.body).toStrictEqual(errorMessage);
});

it("should call Blaise API changePassword endpoint for VALID request even if password is array of characters AND return http status NO_CONTENT_204 ", async () => {
const username = "user1";
const password = ["p", "a", "s", "s", "w", "o", "r", "d"];
blaiseApiMock.setup((api) => api.changePassword(It.isAnyString(), It.isAnyString())).returns(_ => Promise.resolve(null));

const response = await sut.post(`/api/change-password/${username}`)
.set("Authorization", `${mockAuthToken}`)
.field("password", password);

const log = logInfo.mock.calls[0][0];
expect(log).toEqual(`AUDIT_LOG: ${mockUser.name} has successfully changed the password for ${username}`);
expect(response.statusCode).toEqual(204);
blaiseApiMock.verify(a => a.changePassword(It.isValue<string>(username), It.isValue<string>("password")), Times.once());
});

it("should join the password if an array is passed", async () => {
const data: { password: string | string[] } = { password: ["p", "a", "s", "s", "w", "o", "r", "d"] };

if (Array.isArray(data.password)) {
data.password = data.password.join("");
}
expect(data.password).toBe("password");
});
});

describe("PATCH /api/users/:user/rolesAndPermissions endpoint", () => {
Expand Down Expand Up @@ -381,4 +401,46 @@ describe("PATCH /api/users/:user/rolesAndPermissions endpoint", () => {
expect(response.statusCode).toEqual(500);
expect(response.body.message).toContain("Failed to update user role and permissions to admin for testUser");
});
});
});

describe("GET /api/users/:user endpoint", () => {
beforeEach(() => {
blaiseApiMock.reset();
jest.clearAllMocks();
});
afterAll(() => {
blaiseApiMock.reset();
});

it("should call Blaise API getUser endpoint if user param is valid and return user if exists in blaise", async () => {

const user: NewUser = {
name: "test",
password: "password1",
role: "DST",
serverParks: ["gusty", "cma"],
defaultServerPark: "gusty"
};

blaiseApiMock.setup((api) => api.getUser(It.isAnyString())).returns(async () => user);
const response = await sut.get("/api/users/test")
.set("Authorization", `${mockAuthToken}`);

blaiseApiMock.verify(api => api.getUser(It.isValue("test")), Times.once());
expect(response.statusCode).toEqual(200);
expect(response.body.data).toEqual(user);
});

it("should call Blaise API getUser endpoint if user param is valid and return error if user does not exists in blaise", async () => {

const errorMessage = "Blaise API client error";
blaiseApiMock.setup((api) => api.getUser(It.isAnyString())).returns(_ => Promise.reject(errorMessage));
const response = await sut.get("/api/users/invalidUser")
.set("Authorization", `${mockAuthToken}`);

expect(response.statusCode).toEqual(500);
expect(response.body.message).toContain("Error whilst trying to retrieve user");
expect(response.body.error).toEqual(errorMessage);
});

});
Loading
Loading