Skip to content

Commit

Permalink
Add list endpooint to the keyvalue service
Browse files Browse the repository at this point in the history
  • Loading branch information
crufter committed Nov 15, 2023
1 parent 2b91128 commit 18a3688
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/service/keyvalue/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Service } from "../../reflect.js";
import { AuthenticationService } from "../authentication/index.js";
import get from "./get.js";
import set from "./set.js";
import list from "./list.js";

@Service()
export class KeyValueService implements Servicelike {
Expand All @@ -31,6 +32,10 @@ export class KeyValueService implements Servicelike {
return get(this.connection, this.auth, req);
}

list(req: m.ListRequest) {
return list(this.connection, this.auth, req);
}

async _onInit(): Promise<void> {
return null;
}
Expand Down
54 changes: 54 additions & 0 deletions src/service/keyvalue/kv.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,58 @@ describe("keyvalue", () => {
},
});
});

test("list public values", async () => {
await serv.set({
token: tok1,
value: {
key: "publicKey1",
namespace: "test",
public: true,
value: { data: "value1" },
},
});
await serv.set({
token: tok1,
value: {
key: "publicKey2",
namespace: "test",
public: true,
value: { data: "value2" },
},
});

let listRsp = await serv.list({ namespace: "test" });
expect(listRsp.values).toHaveLength(2);
expect(listRsp.values.some((v) => v.key === "publicKey1")).toBeTruthy();
expect(listRsp.values.some((v) => v.key === "publicKey2")).toBeTruthy();
});

test("list private values with token", async () => {
await serv.set({
token: tok1,
value: {
key: "privateKey1",
namespace: "test",
public: false,
value: { data: "value1" },
},
});

let listRsp = await serv.list({ namespace: "test", token: tok1 });
expect(listRsp.values.some((v) => v.key === "privateKey1")).toBeTruthy();
});

test("unauthorized access to private values", async () => {
let listRspNoToken = await serv.list({ namespace: "test" });
let listRspInvalidToken = await serv.list({
namespace: "test",
token: "invalidtoken",
});

expect(listRspNoToken.values.some((v) => v.public === false)).toBeFalsy();
expect(
listRspInvalidToken.values.some((v) => v.public === false)
).toBeFalsy();
});
});
54 changes: 54 additions & 0 deletions src/service/keyvalue/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { DataSource } from "typeorm";
import { Value, ListRequest, ListResponse } from "./models.js";
import { AuthenticationService } from "../authentication/index.js";
import { Role } from "../authentication/models.js";

export default async function list(
connection: DataSource,
auth: AuthenticationService,
req: ListRequest
): Promise<ListResponse> {
let values = await connection
.createQueryBuilder(Value, "value")
.where("value.namespace = :namespace", { namespace: req.namespace })
.getMany();

if (!values.length) {
return {
values: [],
};
}

let filteredValues = [];

for (let v of values) {
if (v.public) {
filteredValues.push(v);
} else {
if (!req.token) {
continue;
}
let tokenRsp = await auth.tokenRead({ token: req.token });
if (v.ownedByUser && v.userId !== tokenRsp.token.user.id) {
continue;
}
if (!v.ownedByUser) {
let departmentIds = getDepartmentIds(tokenRsp.token.user.roles);
if (!departmentIds.includes(v.departmentId)) {
continue;
}
}
filteredValues.push(v);
}
}

return {
values: filteredValues,
};
}

function getDepartmentIds(roles: Role[]): string[] {
return roles
.filter((r) => r.key.includes("department:"))
.map((r) => r.key.split(":")[1]);
}
9 changes: 9 additions & 0 deletions src/service/keyvalue/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,12 @@ export class SetRequest {
export class SetResponse {
value?: Value;
}

export class ListRequest {
token?: string;
namespace?: string;
}

export class ListResponse {
values: Value[];
}

0 comments on commit 18a3688

Please sign in to comment.