This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-express-authz.git

commit 171bc52c489fc5eec4f9d4cd89038f0605a35f9d
Author: Yang Luo <[email protected]>
AuthorDate: Sat Oct 10 02:50:10 2026 +0800

    fix: ignore query string when checking permission
---
 src/authz.ts       | 12 +++++-----
 test/authz.test.ts | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/src/authz.ts b/src/authz.ts
index 3574548..fdc9595 100644
--- a/src/authz.ts
+++ b/src/authz.ts
@@ -20,7 +20,7 @@ export interface Authorizer {
 }
 
 interface AuthorizerConstructor {
-  new(req: Request, res: Response, enforcer: Enforcer): Authorizer
+  new (req: Request, res: Response, enforcer: Enforcer): Authorizer;
 }
 
 // BasicAuthorizer class stores the casbin handler
@@ -58,7 +58,8 @@ class BasicAuthorizer implements Authorizer {
   // Returns true (permission granted) or false (permission forbidden)
   async checkPermission(): Promise<boolean> {
     const { req, enforcer } = this;
-    const { originalUrl: path, method } = req;
+    const { method } = req;
+    const path = req.baseUrl + req.path;
     const user = this.getUserName();
     return enforcer.enforce(user, path, method);
   }
@@ -79,10 +80,9 @@ export function authz(opt: AuthzOptions) {
     }
 
     const authorizer = opt.authorizer
-      ? (typeof opt.authorizer === 'function'
-          ? new opt.authorizer(req, res, enforcer)
-          : opt.authorizer
-        )
+      ? typeof opt.authorizer === 'function'
+        ? new opt.authorizer(req, res, enforcer)
+        : opt.authorizer
       : new BasicAuthorizer(req, res, enforcer);
 
     const isAllowed = await authorizer.checkPermission();
diff --git a/test/authz.test.ts b/test/authz.test.ts
index 40356d8..63e9856 100644
--- a/test/authz.test.ts
+++ b/test/authz.test.ts
@@ -15,6 +15,9 @@
 import server from './server';
 import customServer from './customserver';
 import * as supertest from 'supertest';
+import * as express from 'express';
+import { newEnforcer, newModelFromString, StringAdapter } from 'casbin';
+import { authz } from '../src/authz';
 
 const request = supertest(server);
 const customRequest = supertest(customServer);
@@ -315,3 +318,67 @@ describe('pass through custom server tests', () => {
     });
   });
 });
+
+describe('query string tests', () => {
+  const model = newModelFromString(`
+[request_definition]
+r = sub, obj, act
+
+[policy_definition]
+p = sub, obj, act
+
+[role_definition]
+g = _, _
+
+[policy_effect]
+e = some(where (p.eft == allow))
+
+[matchers]
+m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && r.act == p.act
+`);
+  const policy = new StringAdapter(`
+p, admin, /users, GET
+p, user, /users/:id, GET
+g, alice, user
+g, root, admin
+`);
+  const app = express();
+  app.use(authz({ newEnforcer: newEnforcer(model, policy) }));
+  app.get('/users', (req, res) => res.status(200).json({ handler: 'listUsers' 
}));
+  app.get('/users/:id', (req, res) => res.status(200).json({ handler: 
'getUser' }));
+  const usersRequest = supertest(app);
+  const alice = `Basic ${Buffer.from('alice:password').toString('base64')}`;
+  const root = `Basic ${Buffer.from('root:password').toString('base64')}`;
+
+  test('test: p, user, /users/:id, GET', (done) => {
+    usersRequest
+      .get('/users/42?verbose=1')
+      .set('Authorization', alice)
+      .then((response) => {
+        expect(response.statusCode).toBe(200);
+        expect(response.body.handler).toBe('getUser');
+        done();
+      });
+  });
+
+  test('test: p, admin, /users, GET', (done) => {
+    usersRequest
+      .get('/users?page=1')
+      .set('Authorization', root)
+      .then((response) => {
+        expect(response.statusCode).toBe(200);
+        expect(response.body.handler).toBe('listUsers');
+        done();
+      });
+  });
+
+  test('test: p, admin, /users, GET - 403', (done) => {
+    usersRequest
+      .get('/users/?x=1')
+      .set('Authorization', alice)
+      .then((response) => {
+        expect(response.statusCode).toBe(403);
+        done();
+      });
+  });
+});


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to