-
-
Notifications
You must be signed in to change notification settings - Fork 284
Description
Describe the bug
I am using casl with the Prisma plugin. So far I think everything is working really nicely, but I've noticed that that the accessibleBy
function does not throw an error when a restricted resource is being accessed, instead it seems to simply narrow the search query, so that nothing is returned if the user does not have permission to access the resource.
To Reproduce
For example, here I've defined my ability:
type Action = 'read' | 'create' | 'update' | 'delete' | 'manage';
type AppSubjects =
| 'all'
| Subjects<{
User: User;
Client: Client;
// ...
}>;
export type AppAbility = PureAbility<[Action, AppSubjects], PrismaQuery>;
// the following code is in a function that accepts a user object
const { can, cannot, build } = new AbilityBuilder<AppAbility>(
createPrismaAbility,
);
// for each user role I define different abilities, for example this is for the Operator role
// A more liberal role e.g. an admin or something would be able to read everything to do with
// a client
can(['read', 'update'], 'Client', {
operatorId: { equals: user.id },
}).because('You can only access your own clients.');
// then later on when fetching from the database I am constructing my query something like so:
const filter = accessibleBy(ability).Client
const where = {
AND: [filter, { id: clientId }],
};
const client = await prisma.client.findFirstOrThrow({
where,
include: {
operator: true
},
});
Expected behavior
As mentioned in the documentation I am expecting a ForbiddenError
to be thrown. However it seems that this query simply returns:
An operation failed because it depends on one or more records that were required but not found. Expected a record, found none.
suggesting that the can
simply narrows the search results rather than throw an exception. Using a findFirst
and not using any filters and then asserting afterwards like so:
ForbiddenError.from(ctx.ability).throwUnlessCan(
'read',
subject('Client', client),
);
seems to work, but this does not seem to be the intended behaviour.
CASL Version
"@casl/ability": "^6.5.0",
"@casl/prisma": "^1.4.0",
"@casl/react": "^3.1.0",
Environment:
node: ^18