Skip to content

Commit

Permalink
docs: replace pgpolicy with crudpolicy
Browse files Browse the repository at this point in the history
  • Loading branch information
dhanushreddy291 committed Nov 20, 2024
1 parent 0eac732 commit 624fdfb
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 128 deletions.
39 changes: 13 additions & 26 deletions content/docs/guides/neon-authorize-auth0.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,18 @@ Now that you’ve integrated Auth0 with Neon Authorize, you can securely pass JW

### 1. Add Row-Level Security policies

Below are examples of RLS policies for a **todos** table, designed to restrict access so that users can only create, view, update, or delete their own todos.
Here are examples of implementing RLS policies for a todos table – the Drizzle example leverages the simplified crudPolicy function, while the SQL example demonstrates the use of individual RLS policies.

<Tabs labels={["Drizzle","SQL"]}>

<TabItem>

```typescript shouldWrap
import { InferSelectModel, sql } from 'drizzle-orm';
import { bigint, boolean, pgPolicy, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
import { bigint, boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
import { authenticatedRole, authUid, crudPolicy } from 'drizzle-orm/neon';

// schema for TODOs table
export const todos = pgTable(
'todos',
{
Expand All @@ -162,31 +164,14 @@ export const todos = pgTable(
isComplete: boolean('is_complete').notNull().default(false),
insertedAt: timestamp('inserted_at', { withTimezone: true }).defaultNow().notNull(),
},
(t) => ({
p1: pgPolicy('create todos', {
for: 'insert',
to: 'authenticated',
withCheck: sql`(select auth.user_id() = user_id)`,
// Create RLS policy for the table
(table) => [
crudPolicy({
role: authenticatedRole,
read: authUid(table.userId),
modify: authUid(table.userId),
}),

p2: pgPolicy('view todos', {
for: 'select',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),

p3: pgPolicy('update todos', {
for: 'update',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),

p4: pgPolicy('delete todos', {
for: 'delete',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),
})
]
);

export type Todo = InferSelectModel<typeof todos>;
Expand Down Expand Up @@ -231,6 +216,8 @@ USING ((select auth.user_id()) = user_id);
</TabItem>
</Tabs>

The `crudPolicy` function simplifies policy creation by generating all necessary CRUD policies with a single declaration.

### 2. Run your first authorized query

With RLS policies in place, you can now query the database using JWTs from Auth0 , restricting access based on the user's identity. Here are examples of how you could run authenticated queries from both the backend and the frontend of our sample **todos** application. Highlighted lines in the code samples emphasize key actions related to authentication and querying.
Expand Down
153 changes: 79 additions & 74 deletions content/docs/guides/neon-authorize-clerk.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,29 @@ CREATE EXTENSION IF NOT EXISTS pg_session_jwt;
The integration creates the `authenticated` and `anonymous` roles for you. Let's define table-level permissions for these roles. To allow both roles to read and write to tables in your public schema, run:

```sql
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA public TO authenticated;
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA public TO anonymous;
-- For existing tables
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES
IN SCHEMA public
to authenticated;

GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES
IN SCHEMA public
to anonymous;

-- For future tables
ALTER DEFAULT PRIVILEGES
IN SCHEMA public
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLES
TO authenticated;

ALTER DEFAULT PRIVILEGES
IN SCHEMA public
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLES
TO anonymous;

-- Grant USAGE on "public" schema
GRANT USAGE ON SCHEMA public TO authenticated;
GRANT USAGE ON SCHEMA public TO anonymous;
```

- **Authenticated role**: This role is intended for users who are logged in. Your application should send the authorization token when connecting using this role.
Expand Down Expand Up @@ -123,15 +144,16 @@ Now that you’ve integrated Clerk with Neon Authorize, you can securely pass JW

### 1. Add Row-Level Security policies

Here are some examples of RLS policies for a **todos** table, designed to restrict access so that users can only create, view, update, or delete their own todos.
Here are examples of implementing RLS policies for a todos table – the Drizzle example leverages the simplified crudPolicy function, while the SQL example demonstrates the use of individual RLS policies.

<Tabs labels={["Drizzle","SQL"]}>

<TabItem>

```typescript
import { InferSelectModel, sql } from 'drizzle-orm';
import { bigint, boolean, pgPolicy, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
import { bigint, boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
import { authenticatedRole, authUid, crudPolicy } from 'drizzle-orm/neon';

// schema for TODOs table
export const todos = pgTable(
Expand All @@ -145,32 +167,14 @@ export const todos = pgTable(
isComplete: boolean('is_complete').notNull().default(false),
insertedAt: timestamp('inserted_at', { withTimezone: true }).defaultNow().notNull(),
},
// Create policies for your table
(t) => ({
p1: pgPolicy('create todos', {
for: 'insert',
to: 'authenticated',
withCheck: sql`(select auth.user_id() = user_id)`,
// Create RLS policy for the table
(table) => [
crudPolicy({
role: authenticatedRole,
read: authUid(table.userId),
modify: authUid(table.userId),
}),

p2: pgPolicy('view todos', {
for: 'select',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),

p3: pgPolicy('update todos', {
for: 'update',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),

p4: pgPolicy('delete todos', {
for: 'delete',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),
})
]
);

export type Todo = InferSelectModel<typeof todos>;
Expand Down Expand Up @@ -211,6 +215,8 @@ create policy "Individuals can delete their own todos." on todos for

</Tabs>

The `crudPolicy` function simplifies policy creation by generating all necessary CRUD policies with a single declaration.

### 2. Run your first authorized query

With Row-Level Security (RLS) policies in place, you can securely query the database using JWTs from Clerk, restricting access based on each user’s identity. Here are examples of running authenticated queries from both the backend and frontend of our sample **todos** application. Highlighted lines in the code samples emphasize key actions related to authentication and querying.
Expand Down Expand Up @@ -257,51 +263,50 @@ export async function TodoList() {
```typescript shouldWrap
'use client';

import type { Todo } from '@/app/schema';
import { neon } from '@neondatabase/serverless';
import { useAuth } from '@clerk/nextjs';
import { useEffect, useState } from 'react';

const getDb = (token: string) =>
neon(process.env.NEXT_PUBLIC_DATABASE_AUTHENTICATED_URL!, {
authToken: token, // [!code highlight]
});

export function TodoList() {
const { getToken } = useAuth();
const [todos, setTodos] = useState<Array<Todo>>();

useEffect(() => {
async function loadTodos() {
const authToken = await getToken(); // [!code highlight]

if (!authToken) {
return;
}

const sql = getDb(authToken);

// WHERE filter is optional because of RLS.
// But we send it anyway for performance reasons.
const todosResponse = await
sql('select * from todos where user_id = auth.user_id()'); // [!code highlight]

setTodos(todosResponse as Array<Todo>);
}

loadTodos();
}, [getToken]);

return (
<ul>
{todos?.map((todo) => (
<li key={todo.id}>
{todo.task}
</li>
))}
</ul>
);
}
import type { Todo } from '@/app/schema';
import { neon } from '@neondatabase/serverless';
import { useAuth } from '@clerk/nextjs';
import { useEffect, useState } from 'react';

const getDb = (token: string) =>
neon(process.env.NEXT_PUBLIC_DATABASE_AUTHENTICATED_URL!, {
authToken: token, // [!code highlight]
});

export function TodoList() {
const { getToken } = useAuth();
const [todos, setTodos] = useState<Array<Todo>>();

useEffect(() => {
async function loadTodos() {
const authToken = await getToken(); // [!code highlight]

if (!authToken) {
return;
}

const sql = getDb(authToken);

// WHERE filter is optional because of RLS.
// But we send it anyway for performance reasons.
const todosResponse = await sql('select * from todos where user_id = auth.user_id()'); // [!code highlight]

setTodos(todosResponse as Array<Todo>);
}

loadTodos();
}, [getToken]);

return (
<ul>
{todos?.map((todo) => (
<li key={todo.id}>
{todo.task}
</li>
))}
</ul>
);
}
```

</TabItem>
Expand Down
64 changes: 36 additions & 28 deletions content/docs/guides/neon-authorize-stack-auth.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,29 @@ CREATE EXTENSION IF NOT EXISTS pg_session_jwt;
The integration creates the `authenticated` and `anonymous` roles for you. Let's define table-level permissions for these roles. To allow both roles to read and write to tables in your public schema, run:

```sql shouldWrap
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA public TO authenticated;
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA public TO anonymous;
-- For existing tables
GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES
IN SCHEMA public
to authenticated;

GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES
IN SCHEMA public
to anonymous;

-- For future tables
ALTER DEFAULT PRIVILEGES
IN SCHEMA public
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLES
TO authenticated;

ALTER DEFAULT PRIVILEGES
IN SCHEMA public
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLES
TO anonymous;

-- Grant USAGE on "public" schema
GRANT USAGE ON SCHEMA public TO authenticated;
GRANT USAGE ON SCHEMA public TO anonymous;
```

- **Authenticated role**: This role is intended for users who are logged in. Your application should send the authorization token when connecting using this role.
Expand Down Expand Up @@ -120,16 +141,18 @@ Now that you’ve integrated Stack Auth with Neon Authorize, you can securely pa

### 1. Add Row-Level Security policies

Below are examples of RLS policies for a **todos** table, designed to restrict access so that users can only create, view, update, or delete their own todos.
Here are examples of implementing RLS policies for a todos table – the Drizzle example leverages the simplified crudPolicy function, while the SQL example demonstrates the use of individual RLS policies.

<Tabs labels={["Drizzle","SQL"]}>

<TabItem>

```typescript shouldWrap
import { InferSelectModel, sql } from 'drizzle-orm';
import { bigint, boolean, pgPolicy, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
import { bigint, boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core';
import { authenticatedRole, authUid, crudPolicy } from 'drizzle-orm/neon';

// schema for TODOs table
export const todos = pgTable(
'todos',
{
Expand All @@ -141,31 +164,14 @@ export const todos = pgTable(
isComplete: boolean('is_complete').notNull().default(false),
insertedAt: timestamp('inserted_at', { withTimezone: true }).defaultNow().notNull(),
},
(t) => ({
p1: pgPolicy('create todos', {
for: 'insert',
to: 'authenticated',
withCheck: sql`(select auth.user_id() = user_id)`,
// Create RLS policy for the table
(table) => [
crudPolicy({
role: authenticatedRole,
read: authUid(table.userId),
modify: authUid(table.userId),
}),

p2: pgPolicy('view todos', {
for: 'select',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),

p3: pgPolicy('update todos', {
for: 'update',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),

p4: pgPolicy('delete todos', {
for: 'delete',
to: 'authenticated',
using: sql`(select auth.user_id() = user_id)`,
}),
})
]
);

export type Todo = InferSelectModel<typeof todos>;
Expand Down Expand Up @@ -210,6 +216,8 @@ USING ((select auth.user_id()) = user_id);
</TabItem>
</Tabs>

The `crudPolicy` function simplifies policy creation by generating all necessary CRUD policies with a single declaration.

### 2. Run your first authorized query

With RLS policies in place, you can now query the database using JWTs from Stack Auth, restricting access based on the user's identity. Here are examples of how you could run authenticated queries from both the backend and the frontend of our sample **todos** application. Highlighted lines in the code samples emphasize key actions related to authentication and querying.
Expand Down

0 comments on commit 624fdfb

Please sign in to comment.