Skip to content

Commit dc9a032

Browse files
fix: use default abilities for wildcard abilities
This ensures wildcard role grants (*) only include the standard CRUD operations (create, read, update, delete) and not custom abilities.
1 parent bd4f951 commit dc9a032

File tree

1 file changed

+41
-32
lines changed

1 file changed

+41
-32
lines changed

src/index.ts

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as crypto from "crypto";
22
import { Prisma, PrismaClient, PrismaPromise } from "@prisma/client";
33
import logger from "debug";
4+
import cloneDeep from "lodash/cloneDeep";
45
import difference from "lodash/difference";
56
import flatMap from "lodash/flatMap";
67
import map from "lodash/map";
@@ -191,6 +192,43 @@ export const createRoleName = (name: string) => {
191192
return sanitizeSlug(hashWithPrefix("yates_role_", `${name}`));
192193
};
193194

195+
const getDefaultAbilities = (models: Models[]) => {
196+
const abilities: Partial<DefaultAbilities> = {};
197+
for (const model of models) {
198+
abilities[model] = {
199+
create: {
200+
description: `Create ${model}`,
201+
expression: "true",
202+
operation: "INSERT",
203+
model: model as any,
204+
slug: "create",
205+
},
206+
read: {
207+
description: `Read ${model}`,
208+
expression: "true",
209+
operation: "SELECT",
210+
model: model as any,
211+
slug: "read",
212+
},
213+
update: {
214+
description: `Update ${model}`,
215+
expression: "true",
216+
operation: "UPDATE",
217+
model: model as any,
218+
slug: "update",
219+
},
220+
delete: {
221+
description: `Delete ${model}`,
222+
expression: "true",
223+
operation: "DELETE",
224+
model: model as any,
225+
slug: "delete",
226+
},
227+
};
228+
}
229+
return abilities;
230+
};
231+
194232
// @ts-ignore
195233
export function getBatchId(query: any): string | undefined {
196234
if (query.action !== "findUnique" && query.action !== "findUniqueOrThrow") {
@@ -522,7 +560,6 @@ export const createRoles = async <
522560
[role: string]: AllAbilities<ContextKeys, YModels>[] | "*";
523561
};
524562
}) => {
525-
const abilities: Partial<DefaultAbilities> = {};
526563
// See https://github.com/prisma/prisma/discussions/14777
527564
// We are reaching into the prisma internals to get the data model.
528565
// This is a bit sketchy, but we can get the internal type definition from the runtime library
@@ -540,37 +577,9 @@ export const createRoles = async <
540577
throw new Error(`Invalid models in custom abilities: ${diff.join(", ")}`);
541578
}
542579
}
580+
const defaultAbilities = getDefaultAbilities(models);
581+
const abilities: Partial<DefaultAbilities> = cloneDeep(defaultAbilities);
543582
for (const model of models) {
544-
abilities[model] = {
545-
create: {
546-
description: `Create ${model}`,
547-
expression: "true",
548-
operation: "INSERT",
549-
model: model as any,
550-
slug: "create",
551-
},
552-
read: {
553-
description: `Read ${model}`,
554-
expression: "true",
555-
operation: "SELECT",
556-
model: model as any,
557-
slug: "read",
558-
},
559-
update: {
560-
description: `Update ${model}`,
561-
expression: "true",
562-
operation: "UPDATE",
563-
model: model as any,
564-
slug: "update",
565-
},
566-
delete: {
567-
description: `Delete ${model}`,
568-
expression: "true",
569-
operation: "DELETE",
570-
model: model as any,
571-
slug: "delete",
572-
},
573-
};
574583
if (customAbilities?.[model]) {
575584
for (const ability in customAbilities[model]) {
576585
const operation =
@@ -699,7 +708,7 @@ export const createRoles = async <
699708
;
700709
`);
701710

702-
const wildCardAbilities = flatMap(abilities, (model, modelName) => {
711+
const wildCardAbilities = flatMap(defaultAbilities, (model, modelName) => {
703712
return map(model, (_params, slug) => {
704713
return createAbilityName(modelName, slug);
705714
});

0 commit comments

Comments
 (0)