Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
emranemran committed Mar 22, 2024
1 parent f3070aa commit 3dbccb4
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 22 deletions.
82 changes: 81 additions & 1 deletion packages/api/src/controllers/stream.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
clearDatabase,
startAuxTestServer,
setupUsers,
createProject,
createApiToken,
AuxTestServer,
} from "../test-helpers";
import serverPromise, { TestServer } from "../test-server";
Expand Down Expand Up @@ -107,6 +109,7 @@ describe("controllers/stream", () => {
let nonAdminUser: User;
let nonAdminToken: string;
let nonAdminApiKey: string;
let projectId: string;

beforeEach(async () => {
await server.store.create(mockStore);
Expand All @@ -121,6 +124,9 @@ describe("controllers/stream", () => {
nonAdminApiKey,
} = await setupUsers(server, mockAdminUser, mockNonAdminUser));
client.jwtAuth = adminToken;

projectId = await createProject(client);
expect(projectId).toBeDefined();
});

describe("basic CRUD with JWT authorization", () => {
Expand All @@ -130,6 +136,7 @@ describe("controllers/stream", () => {
const document = {
id: uuid(),
kind: "stream",
projectId: i > 7 ? projectId : undefined,
};
await server.store.create(document);
const res = await client.get(`/stream/${document.id}`);
Expand All @@ -145,6 +152,7 @@ describe("controllers/stream", () => {
id: uuid(),
kind: "stream",
deleted: i > 3 ? true : undefined,
projectId: i > 2 ? projectId : undefined,
} as DBStream;
await server.store.create(document);
const res = await client.get(`/stream/${document.id}`);
Expand All @@ -162,6 +170,32 @@ describe("controllers/stream", () => {
expect(streamsAll.length).toEqual(5);
});

it("should get all streams with admin authorization and specific projectId in query param", async () => {
for (let i = 0; i < 5; i += 1) {
const document = {
id: uuid(),
kind: "stream",
deleted: i > 3 ? true : undefined,
projectId: i > 2 ? projectId : undefined,
} as DBStream;
await server.store.create(document);
const res = await client.get(
`/stream/${document.id}/?projectId=${projectId}`
);
const stream = await res.json();
expect(stream).toEqual(server.db.stream.addDefaultFields(document));
}

const res = await client.get("/stream");
expect(res.status).toBe(200);
const streams = await res.json();
expect(streams.length).toEqual(4);
const resAll = await client.get("/stream?all=1");
expect(resAll.status).toBe(200);
const streamsAll = await resAll.json();
expect(streamsAll.length).toEqual(5);
});

it("should not get empty list with next page", async () => {
const sources = [];
for (let i = 0; i < 5; i += 1) {
Expand Down Expand Up @@ -1040,6 +1074,7 @@ describe("controllers/stream", () => {
});

describe("stream endpoint with api key", () => {
let newApiKey;
beforeEach(async () => {
for (let i = 0; i < 5; i += 1) {
const document = {
Expand All @@ -1051,14 +1086,59 @@ describe("controllers/stream", () => {
const res = await client.get(`/stream/${document.id}`);
expect(res.status).toBe(200);
}

// create a new project
client.jwtAuth = nonAdminToken;
projectId = await createProject(client);
expect(projectId).toBeDefined();
console.log("XXX: created project:", projectId);

// then create a new api-key under that project
const allowedOrigins = ["http://localhost:3000"];
newApiKey = await createApiToken({
client: client,
projectId: projectId,
corsAccess: { allowedOrigins },
jwtAuthToken: nonAdminToken,
});
expect(newApiKey).toMatchObject({
id: expect.any(String),
access: { cors: { allowedOrigins: ["http://localhost:3000"] } },
});

client.jwtAuth = "";
client.apiKey = newApiKey.id;

for (let i = 0; i < 5; i += 1) {
const document = {
id: uuid(),
kind: "stream",
userId: nonAdminUser.id,
projectId: projectId,
};
await server.store.create(document);
const res = await client.get(`/stream/${document.id}`);
expect(res.status).toBe(200);
}

client.jwtAuth = "";
});

it("should get own streams", async () => {
it.only("should get own streams", async () => {
client.apiKey = nonAdminApiKey;
let res = await client.get(`/stream/user/${nonAdminUser.id}`);
expect(res.status).toBe(200);
const streams = await res.json();
console.log("XXX: got nonAdminUser streams: ", streams);
expect(streams.length).toEqual(8);
expect(streams[0].userId).toEqual(nonAdminUser.id);

client.apiKey = newApiKey.id;
console.log("XXX: about to call", client.apiKey, newApiKey.id);
let res2 = await client.get(`/stream/user/${nonAdminUser.id}`);
expect(res2.status).toBe(200);
streams = await res2.json();
console.log("XXX: got newApiKey streams: ", streams);
expect(streams.length).toEqual(3);
expect(streams[0].userId).toEqual(nonAdminUser.id);
});
Expand Down
53 changes: 32 additions & 21 deletions packages/api/src/controllers/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,8 @@ app.get("/:parentId/sessions", authorizer({}), async (req, res) => {
if (
!stream ||
(stream.deleted && !req.isUIAdmin) ||
stream.userId !== req.user.id ||
((stream.projectId ?? "" !== req.project?.id ?? "") && !req.isUIAdmin)
(stream.userId !== req.user.id && !req.isUIAdmin) ||
((stream.projectId ?? "") !== (req.project?.id ?? "") && !req.isUIAdmin)
) {
res.status(404);
return res.json({ errors: ["not found"] });
Expand Down Expand Up @@ -637,9 +637,8 @@ app.get("/sessions/:parentId", authorizer({}), async (req, res) => {
if (
!stream ||
stream.deleted ||
((stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "")) &&
!req.isUIAdmin)
(stream.userId !== req.user.id && !req.isUIAdmin) ||
((stream.projectId ?? "") !== (req.project?.id ?? "") && !req.isUIAdmin)
) {
res.status(404);
return res.json({ errors: ["not found"] });
Expand All @@ -663,6 +662,7 @@ app.get("/sessions/:parentId", authorizer({}), async (req, res) => {
});

app.get("/user/:userId", authorizer({}), async (req, res) => {
console.log("YYY: ", req.user.id, req.params.userId);
const { userId } = req.params;
let { limit, cursor, streamsonly, sessionsonly } = toStringValues(req.query);

Expand All @@ -672,7 +672,7 @@ app.get("/user/:userId", authorizer({}), async (req, res) => {
errors: ["user can only request information on their own streams"],
});
}

console.log("YYY im here");
const query = [
sql`data->>'deleted' IS NULL`,
sql`data->>'userId' = ${userId}`,
Expand Down Expand Up @@ -714,11 +714,16 @@ app.get("/:id", authorizer({}), async (req, res) => {
if (
!stream ||
((stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "") ||
(stream.projectId ?? "") !== (req.project?.id ?? "") ||
stream.deleted) &&
!req.user.admin)
) {
// do not reveal that stream exists
console.log("fialed here");
console.log("req user", req.user.id);
console.log("stream", stream.projectId);
console.log("req project", req.project?.id);
console.log("val", (stream.projectId ?? "") !== (req.project?.id ?? ""));
res.status(404);
return res.json({ errors: ["not found"] });
}
Expand All @@ -727,6 +732,7 @@ app.get("/:id", authorizer({}), async (req, res) => {
if (!raw && stream.lastSessionId) {
const lastSession = await db.stream.get(stream.lastSessionId);
if (!lastSession) {
console.log("fialed here instead");
res.status(404);
return res.json({ errors: ["not found"] });
}
Expand Down Expand Up @@ -760,7 +766,7 @@ app.get("/playback/:playbackId", authorizer({}), async (req, res) => {
if (
!stream ||
((stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "") ||
(stream.projectId ?? "") !== (req.project?.id ?? "") ||
stream.deleted) &&
!req.user.admin)
) {
Expand Down Expand Up @@ -844,7 +850,7 @@ app.post(
if (
!stream ||
((stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "") ||
(stream.projectId ?? "") !== (req.project?.id ?? "") ||
stream.deleted) &&
!(req.user.admin && !stream.deleted))
) {
Expand Down Expand Up @@ -1565,12 +1571,15 @@ app.post(

const stream = await db.stream.get(req.params.id);

if (!stream || stream.deleted || stream.projectId !== req.project?.id) {
if (!stream || stream.deleted) {
res.status(404);
return res.json({ errors: ["stream not found"] });
}

if (stream.userId !== req.user.id) {
if (
stream.userId !== req.user.id ||
(stream.projectId ?? "") !== (req.project?.id ?? "")
) {
res.status(404);
return res.json({ errors: ["stream not found"] });
}
Expand Down Expand Up @@ -1609,12 +1618,15 @@ app.delete("/:id/multistream/:targetId", authorizer({}), async (req, res) => {

const stream = await db.stream.get(id);

if (!stream || stream.deleted || stream.projectId !== req.project?.id) {
if (!stream || stream.deleted) {
res.status(404);
return res.json({ errors: ["stream not found"] });
}

if (stream.userId !== req.user.id) {
if (
stream.userId !== req.user.id ||
(stream.projectId ?? "") !== (req.project?.id ?? "")
) {
res.status(404);
return res.json({ errors: ["stream not found"] });
}
Expand Down Expand Up @@ -1739,7 +1751,7 @@ app.patch("/:id/record", authorizer({}), async (req, res) => {
if (
!stream ||
stream.deleted ||
(stream.projectId ?? "" !== req.project?.id ?? "")
(stream.projectId ?? "") !== (req.project?.id ?? "")
) {
res.status(404);
return res.json({ errors: ["not found"] });
Expand Down Expand Up @@ -1773,9 +1785,8 @@ app.delete("/:id", authorizer({}), async (req, res) => {
if (
!stream ||
stream.deleted ||
((stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "")) &&
!req.user.admin)
(stream.userId !== req.user.id && !req.user.admin) ||
((stream.projectId ?? "") !== (req.project?.id ?? "") && !req.user.admin)
) {
res.status(404);
return res.json({ errors: ["not found"] });
Expand Down Expand Up @@ -1842,7 +1853,7 @@ app.get("/:id/info", authorizer({}), async (req, res) => {
(!req.user.admin &&
(stream.deleted ||
stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "")))
(stream.projectId ?? "") !== (req.project?.id ?? "")))
) {
res.status(404);
return res.json({
Expand Down Expand Up @@ -1915,7 +1926,7 @@ app.patch("/:id/suspended", authorizer({}), async (req, res) => {
(!req.user.admin &&
(stream.deleted ||
stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "")))
(stream.projectId ?? "") !== (req.project?.id ?? "")))
) {
res.status(404);
return res.json({ errors: ["not found"] });
Expand All @@ -1941,7 +1952,7 @@ app.post(
(!req.user.admin &&
(stream.deleted ||
stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "")))
(stream.projectId ?? "") !== (req.project?.id ?? "")))
) {
res.status(404);
return res.json({ errors: ["not found"] });
Expand All @@ -1967,7 +1978,7 @@ app.delete("/:id/terminate", authorizer({}), async (req, res) => {
(!req.user.admin &&
(stream.deleted ||
stream.userId !== req.user.id ||
(stream.projectId ?? "" !== req.project?.id ?? "")))
(stream.projectId ?? "") !== (req.project?.id ?? "")))
) {
res.status(404);
return res.json({ errors: ["not found"] });
Expand Down
30 changes: 30 additions & 0 deletions packages/api/src/test-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,36 @@ export class TestClient {
}
}

export async function createProject(client: TestClient) {
let res = await client.post(`/project`);
const project = await res.json();
return project;
}

export async function createApiToken({
client,
projectId,
tokenName = "test",
corsAccess,
jwtAuthToken,
}: {
client: TestClient;
projectId: string;
tokenName?: string;
corsAccess: ApiToken["access"]["cors"];
jwtAuthToken: string;
}): Promise<string> {
client.jwtAuth = jwtAuthToken;
let res = await client.post(`/api-token/?projectId=${projectId}`, {
name: tokenName,
access: { cors: corsAccess },
});
client.jwtAuth = null;
const apiKeyObj = await res.json();
console.log("XXX: create token: ", apiKeyObj);
return apiKeyObj;
}

export async function createUser(
server: TestServer,
client: TestClient,
Expand Down

0 comments on commit 3dbccb4

Please sign in to comment.