Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
LucianBuzzo committed Mar 28, 2024
1 parent cd816e8 commit c53cee1
Showing 1 changed file with 18 additions and 22 deletions.
40 changes: 18 additions & 22 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,6 @@ const setRLS = async <ContextKeys extends string, YModel extends Models>(
if (!rawExpression) {
throw new Error("Expression must be defined for RLS abilities");
}
debug("Calculating RLS expression from", rawExpression);

const expression = await expressionToSQL(rawExpression, table);

// Check if RLS exists
const policyName = roleName;
Expand All @@ -327,39 +324,35 @@ const setRLS = async <ContextKeys extends string, YModel extends Models>(
row.ability_model === table && row.ability_policy_name === policyName,
);

debug("Creating RLS policy", policyName);
debug("On table", table);
debug("For operation", operation);
debug("To role", roleName);
debug("With expression", expression);
debug("Found existing ability", existingAbility);

let shouldUpdateAbilityTable = false;

// IF RLS doesn't exist or expression is different, set RLS
if (!existingAbility) {
// If we're transitioning from the v3 yates lookups, we need to check the pg_policies table
// This only happens if the YATES_COMPAT_MODE env var is set to true
debug("Creating RLS policy for", roleName, "on", table, "for", operation);
const expression = await expressionToSQL(rawExpression, table);

// If the operation is an insert or update, we need to use a different syntax as the "WITH CHECK" expression is used.
if (operation === "INSERT") {
await prisma.$queryRawUnsafe(`
CREATE POLICY ${policyName} ON "public"."${table}" FOR ${operation} TO ${roleName} WITH CHECK (${expression});
`);
CREATE POLICY ${policyName} ON "public"."${table}" FOR ${operation} TO ${roleName} WITH CHECK (${expression});
`);
} else {
await prisma.$queryRawUnsafe(`
CREATE POLICY ${policyName} ON "public"."${table}" FOR ${operation} TO ${roleName} USING (${expression});
`);
CREATE POLICY ${policyName} ON "public"."${table}" FOR ${operation} TO ${roleName} USING (${expression});
`);
}
shouldUpdateAbilityTable = true;
} else if (existingAbility.ability_expression !== expression) {
} else if (existingAbility.ability_expression !== rawExpression.toString()) {
debug("Updating RLS policy for", roleName, "on", table, "for", operation);
const expression = await expressionToSQL(rawExpression, table);
if (operation === "INSERT") {
await prisma.$queryRawUnsafe(`
ALTER POLICY ${policyName} ON "public"."${table}" TO ${roleName} WITH CHECK (${expression});
`);
ALTER POLICY ${policyName} ON "public"."${table}" TO ${roleName} WITH CHECK (${expression});
`);
} else {
await prisma.$queryRawUnsafe(`
ALTER POLICY ${policyName} ON "public"."${table}" TO ${roleName} USING (${expression});
`);
ALTER POLICY ${policyName} ON "public"."${table}" TO ${roleName} USING (${expression});
`);
}
shouldUpdateAbilityTable = true;
}
Expand All @@ -373,7 +366,9 @@ const setRLS = async <ContextKeys extends string, YModel extends Models>(
ability_policy_name: policyName,
ability_description: description ?? "",
ability_operation: operation,
ability_expression: expression,
// We store the string representation of the expression so that
// we can compare it later without having to recompute the SQL
ability_expression: rawExpression.toString(),
}),
]);
}
Expand Down Expand Up @@ -482,6 +477,7 @@ export const createRoles = async <
// If this a first time setup, we may need to import existing abilities from
// the pg_policies table into the new abilities lookup table.
if (existingAbilities.length === 0) {
debug('No existing abilities found, importing from "pg_policies" table');
const pgPolicies: PgPolicy[] = await prisma.$queryRawUnsafe(`
select * from pg_catalog.pg_policies where policyname like 'yates%'
`);
Expand Down

0 comments on commit c53cee1

Please sign in to comment.