-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial blitz-guard commit * Remove try/catch to let Quirrel and the log drain to catch * Comment for now * Comment unused parts * Update blitz-guard package - Update package - Add tests - Add prisma test environment * Remove unused names * Fix validation issue * Add Gh Actions config * Try new config * User yarn to call blitz * New config * Fix yml 😠 * Change schema random generation * Remove migrations step * Unify the test environments - Make Prisma Test Env inherit from JSDom - Remove unused test env - Enable Home test * Change text for word in fakes * Test new workflow * Testing this * Don't fail on migrate * Updated prisma executable * Add createReaction tests * Reset DATABASE_URL on teardown * Add deleteReaction tests * Fix logo width and height * Remove can from unauthorize * Removed unused url * Updates to 0.3.0 of blitz guard (#23) * Updates to 0.2.0 of blitz guard * Uses blitz-guard 0.3.0 * Remove unused console.log * Make ability work - `cannot` everything before - Add a fail if no exception is raised * Remove unnecessary queries * Throw an error if no message * Improve README - Remove unnecessary migrate call - Add testing guides to README * Add missing fails * Update README.md Co-authored-by: Nicolas Torres <[email protected]> Co-authored-by: dhernandez-ingsw <[email protected]>
- Loading branch information
1 parent
a2fa003
commit 963a496
Showing
33 changed files
with
1,125 additions
and
159 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
name: Run Tests | ||
on: push | ||
|
||
jobs: | ||
container-job: | ||
runs-on: ubuntu-latest | ||
container: node:14 | ||
|
||
services: | ||
postgres: | ||
image: postgres:12 | ||
env: | ||
POSTGRES_PASSWORD: postgres | ||
POSTGRES_USER: postgres | ||
POSTGRES_DB: db | ||
ports: | ||
- 5432:5432 | ||
# Set health checks to wait until postgres has started | ||
options: >- | ||
--health-cmd pg_isready | ||
--health-interval 10s | ||
--health-timeout 5s | ||
--health-retries 5 | ||
steps: | ||
- name: Check out repository code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Cache dependencies | ||
uses: actions/cache@v2 | ||
with: | ||
path: "**/node_modules" | ||
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} | ||
|
||
- name: Install dependencies | ||
run: yarn install --frozen-lockfile | ||
|
||
- name: Run tests | ||
run: yarn test | ||
env: | ||
DATABASE_URL: postgresql://postgres:postgres@postgres:${{ job.services.postgres.ports[5432] }}/db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { User } from "@prisma/client" | ||
import { WebAPICallResult, WebClient } from "@slack/web-api" | ||
import { Channel } from "../types" | ||
|
||
export default async function getUserChannels({ user }: { user: User }) { | ||
const web = new WebClient(user.slackAccessToken) | ||
const result = (await web.users.conversations({ | ||
user: user?.slackUserId, | ||
types: "public_channel,private_channel", | ||
})) as WebAPICallResult & { channels: Channel[] } | ||
|
||
return result.channels | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { NotFoundError } from "blitz" | ||
import db from "db" | ||
import { GuardBuilder, PrismaModelsType } from "@blitz-guard/core" | ||
import getUserChannels from "app/channels/lib/getUserChannels" | ||
import { UpdateMessageInputType } from "app/messages/mutations/updateMessage" | ||
import { DeleteMessageInput } from "app/messages/mutations/deleteMessage" | ||
import { GetMessageInput } from "app/messages/queries/getMessage" | ||
import { CreateReactionInput } from "app/reactions/mutations/createReaction" | ||
import { DeleteReactionInput } from "app/reactions/mutations/deleteReaction" | ||
|
||
type ExtendedResourceTypes = PrismaModelsType<typeof db> | ||
|
||
export default GuardBuilder<ExtendedResourceTypes>(async (ctx, { can, cannot }) => { | ||
cannot("manage", "all") | ||
if (ctx.session.isAuthorized()) { | ||
// Messages | ||
can("read", "message", async ({ where }: GetMessageInput) => { | ||
const messageRequest = db.message.findFirst({ where: { id: where?.id } }) | ||
const userRequest = db.user.findUnique({ where: { id: ctx.session.userId ?? undefined } }) | ||
const [message, user] = await db.$transaction([messageRequest, userRequest]) | ||
if (!message || !user) throw new NotFoundError() | ||
|
||
const channels = await getUserChannels({ user }) | ||
|
||
return !!channels.find((channel) => channel.id === message.slackChannelId) | ||
}) | ||
can("create", "message") | ||
can("update", "message", async ({ where }: UpdateMessageInputType) => { | ||
const message = await db.message.findUnique({ where: { id: where.id } }) | ||
if (!message) throw new NotFoundError() | ||
return message.userId === ctx.session.userId | ||
}) | ||
can("delete", "message", async ({ where }: DeleteMessageInput) => { | ||
const message = await db.message.findUnique({ where: { id: where.id } }) | ||
if (!message) throw new NotFoundError() | ||
return message.userId === ctx.session.userId | ||
}) | ||
|
||
// Reactions | ||
can("create", "reaction", async ({ data }: CreateReactionInput) => { | ||
const messageRequest = db.message.findUnique({ | ||
where: { id: data?.message?.connect?.id as string }, | ||
}) | ||
const userRequest = db.user.findUnique({ where: { id: ctx.session.userId ?? undefined } }) | ||
const [message, user] = await db.$transaction([messageRequest, userRequest]) | ||
if (!message || !user) throw new NotFoundError() | ||
|
||
const channels = await getUserChannels({ user }) | ||
|
||
return !!channels.find((channel) => channel.id === message.slackChannelId) | ||
}) | ||
can("delete", "reaction", async ({ where }: DeleteReactionInput) => { | ||
const reactionRequest = db.reaction.findUnique({ | ||
where: { id: where?.id }, | ||
include: { message: true }, | ||
}) | ||
const userRequest = db.user.findUnique({ where: { id: ctx.session.userId ?? undefined } }) | ||
const [reaction, user] = await db.$transaction([reactionRequest, userRequest]) | ||
if (!reaction || !user) throw new NotFoundError() | ||
|
||
if (reaction.userId !== user.id) return false | ||
|
||
const channels = await getUserChannels({ user }) | ||
|
||
return !!channels.find((channel) => channel.id === reaction?.message?.slackChannelId) | ||
}) | ||
can("read", "reaction") | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import Guard from "../ability" | ||
export default Guard.getAbility |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { AuthorizationError } from "blitz" | ||
import db from "db" | ||
import faker from "faker" | ||
import { getUserAttributes } from "test/factories" | ||
import { getSession } from "test/utils" | ||
import createMessage from "./createMessage" | ||
|
||
beforeAll(async () => { | ||
await db.message.deleteMany({}) | ||
await db.user.deleteMany({}) | ||
}) | ||
|
||
afterAll(async () => { | ||
await db.$disconnect() | ||
}) | ||
|
||
describe("createMessage", () => { | ||
describe("when user is not authorized", () => { | ||
it("throws an AuhtorizationError", async () => { | ||
try { | ||
await createMessage( | ||
{ | ||
data: { | ||
body: faker.lorem.paragraphs(), | ||
title: faker.lorem.word(10), | ||
slackChannelId: faker.lorem.slug(), | ||
}, | ||
}, | ||
getSession() | ||
) | ||
fail("This call should throw an exception") | ||
} catch (e) { | ||
let error = e as AuthorizationError | ||
expect(error.statusCode).toEqual(403) | ||
expect(error.name).toEqual("AuthorizationError") | ||
} | ||
}) | ||
}) | ||
|
||
it("creates the message", async () => { | ||
const user = await db.user.create(getUserAttributes()) | ||
const previousCount = await db.message.count() | ||
const returnedValue = await createMessage( | ||
{ | ||
data: { | ||
body: faker.lorem.paragraphs(), | ||
title: faker.lorem.word(10), | ||
slackChannelId: faker.lorem.slug(), | ||
}, | ||
}, | ||
getSession({ user }) | ||
) | ||
const currentCount = await db.message.count() | ||
expect(currentCount).toEqual(previousCount + 1) | ||
expect(returnedValue.id).not.toBeNull() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
963a496
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: