Skip to content
This repository was archived by the owner on Dec 8, 2023. It is now read-only.

feat: add a basic Oso pattern #50

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion .grit/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
engine.log
.gritmodules
*.log
57 changes: 57 additions & 0 deletions .grit/patterns/Oso.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Use Oso for authorization

```grit
language js

// Look for conditionals
`if ($cond) { $effect }` where {
$cond <: contains or {
// Find any of our hand-rolled functions
`$user.isAdmin`, `$user.isManager`
} => `await oso.authorize($user, $action, $resource)` where {
// Guess the action
$action = guess(hint="action to take")
// Guess the target:
$resource = guess(hint="resource to check")
}
}
```

## Next.js sample

```js
import { withIronSessionApiRoute } from "iron-session/next";
import { sessionOptions } from "lib/session";
import { Octokit } from "octokit";

import type { Endpoints } from "@octokit/types";
import { NextApiRequest, NextApiResponse } from "next";

export type Events =
Endpoints["GET /users/{username}/events"]["response"]["data"];

const octokit = new Octokit();

async function eventsRoute(req: NextApiRequest, res: NextApiResponse<Events>) {
const user = req.session.user;
const targetUser = req.body.data.user;

if (!user || user.isLoggedIn === false || !user.isAdmin()) {
res.status(401).end();
return;
}

try {
const { data: events } =
await octokit.rest.activity.listPublicEventsForUser({
username: user.login,
});

res.json(events);
} catch (error) {
res.status(200).json([]);
}
}

export default withIronSessionApiRoute(eventsRoute, sessionOptions);
```