From 641c061fe86c96045a662fb12312c18fede1c767 Mon Sep 17 00:00:00 2001 From: Igor Savin Date: Sun, 17 Jan 2021 00:55:53 +0200 Subject: [PATCH 1/2] Add support for specifying custom logger --- README.md | 1 + plugin.d.ts | 3 ++- plugin.js | 5 +++-- test/casbinRest.test.js | 31 +++++++++++++++++++++++++++++++ test/plugin.test-d.ts | 1 + 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2696fc4..8e06835 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ The API exposed by this plugin is the configuration options: | `getObj` | `Request => string` | Extracts `obj` from the request | `r => r.url` | | `getAct` | `Request => string` | Extracts `act` from the request | `r => r.method` | | `onDeny` | `(Reply, sub, obj, act) => any` | Invoked when Casbin's `enforce` resolves to false | Returns a `403 Forbidden` error | +| `log` | `(Fastify, Request, sub, obj, act => void` | Invoked before invoking Casbin's `enforce` | Logs using fastify.log.info | | `hook` | `'onRequest', 'preParsing', 'preValidation', 'preHandler'` | Which lifecycle to use for performing the check | `'preHandler'` | Note that extraction rules defined within route options take precedence over the rules defined in the plugin options. diff --git a/plugin.d.ts b/plugin.d.ts index af78529..5f26a64 100644 --- a/plugin.d.ts +++ b/plugin.d.ts @@ -1,6 +1,6 @@ /// -import { FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify' +import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest } from 'fastify' declare module 'fastify' { interface RouteShorthandOptions { @@ -25,6 +25,7 @@ export interface FastifyCasbinRestOptions { getObj?(request: FastifyRequest): string getAct?(request: FastifyRequest): string onDeny?(reply: FastifyReply, sub: string, obj: string, act: string): void + log?(fastify: FastifyInstance, request: FastifyRequest, sub: string, obj: string, act: string): void hook?: Hook } diff --git a/plugin.js b/plugin.js index 033666f..8f400dd 100644 --- a/plugin.js +++ b/plugin.js @@ -10,11 +10,13 @@ const defaultOptions = { onDeny: (reply, sub, obj, act) => { throw new Forbidden(`${sub} not allowed to ${act} ${obj}`) }, + log: (fastify, request, sub, obj, act) => { fastify.log.info({ sub, obj, act }, 'Invoking casbin enforce') }, hook: 'preHandler' } async function fastifyCasbinRest (fastify, options) { options = { ...defaultOptions, ...options } + const { log } = options fastify.addHook('onRoute', routeOptions => { // add option to turn it on for all routes @@ -39,8 +41,7 @@ async function fastifyCasbinRest (fastify, options) { const obj = getObj(request) const act = getAct(request) - fastify.log.info({ sub, obj, act }, 'Invoking casbin enforce') - + log(fastify, request, sub, obj, act) if (!(await fastify.casbin.enforce(sub, obj, act))) { await options.onDeny(reply, sub, obj, act) } diff --git a/test/casbinRest.test.js b/test/casbinRest.test.js index 47fadc7..3693fd8 100644 --- a/test/casbinRest.test.js +++ b/test/casbinRest.test.js @@ -205,6 +205,37 @@ test('supports specifying custom hooks', t => { }) }) +test('supports specifying custom logger', t => { + t.plan(5) + + const fastify = Fastify() + fastify.register(makeStubCasbin()) + fastify.register(plugin, { + log: (fastify, request, sub, obj, act) => { + t.equal(sub, 'a') + t.equal(obj, 'b') + t.equal(act, 'c') + }, + getSub: _request => 'a', + getObj: _request => 'b', + getAct: _request => 'c' + }) + + fastify.get('/', { + casbin: { rest: true } + }, () => 'ok') + + fastify.ready(async err => { + t.error(err) + + fastify.casbin.enforce.resolves(true) + + t.equal((await fastify.inject('/')).statusCode, 200) + + fastify.close() + }) +}) + test('supports overriding plugin rules on route level', t => { t.plan(4) diff --git a/test/plugin.test-d.ts b/test/plugin.test-d.ts index 86cbedf..4ee0756 100644 --- a/test/plugin.test-d.ts +++ b/test/plugin.test-d.ts @@ -7,6 +7,7 @@ const server = fastify() server.register(casbinRest) server.register(casbinRest, { + log: (fastify, request, sub, obj, act) => { fastify.log.info({ sub, obj, act }, 'Invoking casbin enforce') }, onDeny: (reply, sub, obj, act) => { expectType(reply) expectType(sub) From 8c3c5de0ecd5b0e6f2065b7d742105a22a00944c Mon Sep 17 00:00:00 2001 From: Igor Savin Date: Sun, 17 Jan 2021 01:13:11 +0200 Subject: [PATCH 2/2] Fix failing test --- package.json | 14 +++++++------- test/casbinRest.test.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index e7382c2..e1a01eb 100644 --- a/package.json +++ b/package.json @@ -38,14 +38,14 @@ "http-errors": "^1.8.0" }, "devDependencies": { - "@types/node": "^14.14.6", - "fastify": "^3.7.0", + "@types/node": "^14.14.21", + "fastify": "^3.10.1", "pre-commit": "^1.2.2", - "sinon": "^9.2.1", + "sinon": "^9.2.3", "snazzy": "^9.0.0", - "standard": "^16.0.1", - "tap": "^14.10.8", - "tsd": "^0.13.1", - "typescript": "^4.0.5" + "standard": "^16.0.3", + "tap": "^14.11.0", + "tsd": "^0.14.0", + "typescript": "^4.1.3" } } diff --git a/test/casbinRest.test.js b/test/casbinRest.test.js index 3693fd8..4fee20e 100644 --- a/test/casbinRest.test.js +++ b/test/casbinRest.test.js @@ -32,7 +32,7 @@ test('throws if no casbin decorator exists', t => { fastify.register(plugin) fastify.ready(err => { - t.is(err.message, "The decorator 'casbin' is not present in Fastify") + t.is(err.message, "The decorator 'casbin' required by 'fastify-casbin-rest' is not present in Fastify") fastify.close() })