Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pass query args to list access control functions #420

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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