Skip to content

Commit

Permalink
feat: pass query args to list access control functions
Browse files Browse the repository at this point in the history
fixes issue keystonejs#419
  • Loading branch information
SavelevMatthew committed Feb 29, 2024
1 parent ee00f7f commit a9f0d15
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/neat-moons-give.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@keystonejs/access-control': minor
'@keystonejs/keystone': minor
---

Pass query args to list access control functions
4 changes: 3 additions & 1 deletion docs/api/access-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ interface AccessInput {
gqlName?: string;
itemId?: string;
itemIds?: [string];
args?: {}
}

type StaticAccess = boolean;
Expand All @@ -91,7 +92,7 @@ the list `User` it would match the input type `UserWhereInput`.
`AccessInput` has the following properties:

| Property | Description |
| ------------------------ | --------------------------------------------------------------------------------------------- |
|--------------------------|-----------------------------------------------------------------------------------------------|
| `authentication` | The currently authenticated user. |
| `authentication.item` | The details of the current user. Will be `undefined` for anonymous users. |
| `authentication.listKey` | The list key of the currently authenticated user. Will be `undefined` for anonymous users. |
Expand All @@ -102,6 +103,7 @@ the list `User` it would match the input type `UserWhereInput`.
| `itemId` | The `id` of the item being updated/deleted in singular `update` and `delete` operations. |
| `itemIds` | The `ids` of the items being updated/deleted in multiple `update` and `delete` operations. |
| `context` | The `context` of the originating GraphQL operation. |
| `args` | Arguments of GraphQL operation |

When resolving `StaticAccess`:

Expand Down
3 changes: 3 additions & 0 deletions packages/access-control/src/access-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type ListAccessArgs = {
originalInput?: any;
itemId?: any;
itemIds?: any;
args?: any;
};
type FieldAccessArgs = {
operation: keyof FieldAccess<FieldAccessArgs>;
Expand Down Expand Up @@ -329,6 +330,7 @@ export async function validateListAccessControl({
itemId,
itemIds,
context,
args,
}: { access: ListAccess<ListAccessArgs> } & ListAccessArgs) {
// Either a boolean or an object describing a where clause
let result: Static | Declarative = false;
Expand All @@ -345,6 +347,7 @@ export async function validateListAccessControl({
itemId,
itemIds,
context,
args,
});
}

Expand Down
3 changes: 2 additions & 1 deletion packages/keystone/lib/Keystone/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ module.exports = class Keystone {
listKey,
originalInput,
operation,
{ gqlName, itemId, itemIds, context } = {}
{ gqlName, itemId, itemIds, context, args } = {}
) => {
return validateListAccessControl({
access: access[schemaName],
Expand All @@ -131,6 +131,7 @@ module.exports = class Keystone {
itemId,
itemIds,
context,
args,
});
},
{ isPromise: true }
Expand Down
4 changes: 2 additions & 2 deletions packages/keystone/lib/ListTypes/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ module.exports = class List {
}

async listQuery(args, context, gqlName, info, from) {
const access = await this.checkListAccess(context, undefined, 'read', { gqlName });
const access = await this.checkListAccess(context, undefined, 'read', { gqlName, args });

return this._itemsQuery(mergeWhereClause(args, access), { context, info, from });
}
Expand All @@ -494,7 +494,7 @@ module.exports = class List {
// on what the user requested
// Evaluation takes place in ../Keystone/index.js
getCount: async () => {
const access = await this.checkListAccess(context, undefined, 'read', { gqlName });
const access = await this.checkListAccess(context, undefined, 'read', { gqlName, args });

const { count } = await this._itemsQuery(mergeWhereClause(args, access), {
meta: true,
Expand Down

0 comments on commit a9f0d15

Please sign in to comment.