Skip to content

Commit

Permalink
Merge pull request #97 from smartive/break/change-permission-messages
Browse files Browse the repository at this point in the history
break: Change permission messages to include user role
  • Loading branch information
dwirz authored Nov 9, 2023
2 parents a126d8a + e14512b commit fe6f7c2
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/client/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export const getEntityQuery = (
role: string,
visibleRelationsByRole: VisibleRelationsByRole,
typesWithSubRelations: string[]
) => `query Admin${model.name} ($id: ID!) {
) => `query Get${model.name}Entity ($id: ID!) {
data: ${typeToField(model.name)}(where: { id: $id }) {
${displayField(model)}
${model.fields.filter(and(isSimpleField, isQueriableBy(role))).map(({ name }) => name)}
Expand Down
4 changes: 2 additions & 2 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class UserInputError extends GraphQLError {
}

export class PermissionError extends ForbiddenError {
constructor(action: PermissionAction, what: string, why: string) {
super(`You do not have sufficient permissions to ${action.toLowerCase()} ${what} (${why}).`);
constructor(role: string, action: PermissionAction, what: string, why: string) {
super(`Role ${role} does not have sufficient permissions to ${action.toLowerCase()} ${what} (${why}).`);
}
}
22 changes: 16 additions & 6 deletions src/permissions/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const getEntityToMutate = async (
.map(([key, value]) => `${key}: ${value}`)
.join(', ')}`
);
throw new PermissionError(action, `this ${model.name}`, 'no available permissions applied');
throw new PermissionError(ctx.user.role, action, `this ${model.name}`, 'no available permissions applied');
}

if (model.parent) {
Expand All @@ -139,7 +139,7 @@ export const checkCanWrite = async (
return;
}
if (permissionStack === false) {
throw new PermissionError(action, model.plural, 'no applicable permissions');
throw new PermissionError(ctx.user.role, action, model.plural, 'no applicable permissions');
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- using `select(1 as any)` to instantiate an "empty" query builder
Expand All @@ -157,7 +157,12 @@ export const checkCanWrite = async (

const fieldPermissions = field[action === 'CREATE' ? 'creatable' : 'updatable'];
if (fieldPermissions && typeof fieldPermissions === 'object' && !fieldPermissions.roles?.includes(ctx.user.role)) {
throw new PermissionError(action, `this ${model.name}'s ${field.name}`, 'field permission not available');
throw new PermissionError(
ctx.user.role,
action,
`this ${model.name}'s ${field.name}`,
'field permission not available'
);
}

linked = true;
Expand All @@ -172,7 +177,12 @@ export const checkCanWrite = async (
}

if (fieldPermissionStack === false || !fieldPermissionStack.length) {
throw new PermissionError(action, `this ${model.name}'s ${field.name}`, 'no applicable permissions on data to link');
throw new PermissionError(
ctx.user.role,
action,
`this ${model.name}'s ${field.name}`,
'no applicable permissions on data to link'
);
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
Expand All @@ -187,10 +197,10 @@ export const checkCanWrite = async (
if (linked) {
const canMutate = await query;
if (!canMutate) {
throw new PermissionError(action, `this ${model.name}`, 'no linkable entities');
throw new PermissionError(ctx.user.role, action, `this ${model.name}`, 'no linkable entities');
}
} else if (action === 'CREATE') {
throw new PermissionError(action, `this ${model.name}`, 'no linkable entities');
throw new PermissionError(ctx.user.role, action, `this ${model.name}`, 'no linkable entities');
}
};

Expand Down
1 change: 1 addition & 0 deletions src/resolvers/selects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const applySelects = (node: ResolverNode, query: Knex.QueryBuilder, joins

if (typeof field.queriable === 'object' && !field.queriable.roles?.includes(node.ctx.user.role)) {
throw new PermissionError(
node.ctx.user.role,
'READ',
`${node.model.name}'s field "${field.name}"`,
'field permission not available'
Expand Down

0 comments on commit fe6f7c2

Please sign in to comment.