node-casbin / sequelize-adapter Goto Github PK
View Code? Open in Web Editor NEWSequelize adapter for Casbin
Home Page: https://github.com/casbin/node-casbin
License: Apache License 2.0
Sequelize adapter for Casbin
Home Page: https://github.com/casbin/node-casbin
License: Apache License 2.0
Hi, thanks for this library ❤️
Would it be possible to support changing the default casbin_rule
table name? We have our own convention of table names and at the moment casbin_rule
sticks out.
I'm thinking of something like:
const adapter = await SequelizeAdapter.newAdapter({
username: config.db.username,
// ...
tableName: 'not_casbin_rule`
});
Happy to make a PR for it.
Hi,
I was wondering if there was a way to load initial policies from a file and then make them consistent in the sequelize database we reference.
The use case would be this:
It appears that this issue has already been raised and supposedly, it was solved with this PR, but even after installing the latest version of the adapter(v2.6.1), the problem still persists. In the previous issue (as this) provided three sets of options for connecting to different schemas in the same database. However, when running the code, the last adapter seems to override the other two, preventing you from opening different database connections. The only difference among the options is the schema.
const pgOptions1 = {
username: 'some_user',
host: 'some_host',
port: XXXX,
password: 'some_password',
database: 'some_db',
schema: "tenant1",
logging: false,
dialect: 'postgres'
};
const pgOptions2 = {
username: 'some_user',
host: 'some_host',
port: XXXX,
password: 'some_password',
database: 'some_db',
schema: "tenant2",
logging: false,
dialect: 'postgres'
};
const pgOptions3 = {
username: 'some_user',
host: 'some_host',
port: XXXX,
password: 'some_password',
database: 'some_db',
schema: "tenant3",
logging: false,
dialect: 'postgres'
};
async function run() {
const casbinAdapter1 = await SequelizeAdapter.newAdapter(pgOptions1);
const casbinAdapter2 = await SequelizeAdapter.newAdapter(pgOptions2);
const casbinAdapter3 = await SequelizeAdapter.newAdapter(pgOptions3);
const enforcer1 = await casbin.newEnforcer('abac_model.conf', casbinAdapter1);
const enforcer2 = await casbin.newEnforcer('abac_model.conf', casbinAdapter2);
const enforcer3 = await casbin.newEnforcer('abac_model.conf', casbinAdapter3);
const p = ['sub', 'obj', 'act'];
// this add policy at tenant3
await enforcer2.addPolicy(...p);
}
run().catch(console.error);
Could you please verify if the problem is resolved?
Thank you in advance
Hi, I've just started using Casbin and am considering using this library, but there's a few things about it that feel a bit unsafe or suboptimal to me, so I was wondering if you'd be happy to receive a pull request that made the following changes:
sync
in open
Sequelize docs suggest use migrations rather than sync
in production: https://sequelize.org/master/manual/getting-started.html#note-for-production and there are several blogs and stack overflow posts suggesting the same for safety reasons. Removing the call to sync
would require users to create the table themselves, however the library could provide a reference migration file to make this easier.
savePolicy
in a transactionCurrently the savePolicy
function drops and recreates the policy table, then inserts the policy rules in memory into the newly created table one at a time. As this isn't done in a transaction, any errors that occurred would mean the policy would be partially or wholly lost - a serious issue. I think this should be easy enough to fix by truncating the table rather than dropping it and wrapping the whole thing in a transaction.
savePolicy
A less serious issue of performance rather than safety, the savePolicy
function could be made much faster by using bulk rather than one-by-one insert.
sequelize-typescript
Sequelize now includes types, so there's an opportunity to remove this dependency. It may require refactoring CasbinRule
a little as I don't believe the Sequelize types support annotations in the same way that sequelize-typescript
does.
Would you be happy to receive a PR that made these changes? And if so would you prefer separate PRs for each individual change?
Hi All , I am trying to integrate casbin . Data is getting saved in DB using addPolicy
When i try to access data : await e.enforce("alice", "data1", "read"); i am getting false
Can anyone help me with this
?
It seems like if I try to create an adapter instance, the last one overrides all previously created.
For my application, I have multiple tenants and per tenant Postgres schema is different.
example:
pgOptions1 has schema name as *tenant1*
pgOptions2 has schema name as *tenant2*
pgOptions3 has schema name as *tenant3*
const casbinAdapter1 = await SequelizeAdapter.newAdapter(pgOptions1);
const casbinAdapter2 = await SequelizeAdapter.newAdapter(pgOptions2);
const casbinAdapter3 = await SequelizeAdapter.newAdapter(pgOptions3);
if I init above 3 adapters then it seems like casbinAdapter1 and casbinAdapter2 instance are equivalent to casbinAdapter3.
So if I use any adapter in enforcer it always points to the last db adapter instance i.e. tenant3 schema instance.
I'm using MySQL and having some troubles with the time to add a new user policy. This is taking around 6 seconds. Is this the expected time?
My express.js route
app.put('/role/user/add', async (req, res) => {
const status = await addUserRole(req.body.user, req.body.role_name);
send_response(res, status);
})
Function to insert a new user role.
async addUserRole(user_name, role_name){
const status = await this.enforcer.addNamedGroupingPolicy('g', user_name, role_name);
await this.enforcer.savePolicy();
return status;
}
Please fix it. Thanks!
I can't call addPolicy when using Sequelize v5. I get the following error:
TypeError: sequelize_1.Model[(staticMethodPrefix + "conformOptions")] is not a function
at Function.BaseModel.prepareInstantiationOptions (node_modules/sequelize-typescript/lib/models/BaseModel.js:97:69)
at new Model (node_modules/sequelize-typescript/lib/models/v4/Model.js:8:45)
at new CasbinRule (node_modules/casbin-sequelize-adapter/lib/casbinRule.js:26:18)
at new <anonymous> (node_modules/casbin-sequelize-adapter/lib/adapter.js:28:12)
at SequelizeAdapter.savePolicyLine (node_modules/casbin-sequelize-adapter/lib/adapter.js:122:22)
at SequelizeAdapter.<anonymous> (node_modules/casbin-sequelize-adapter/lib/adapter.js:175:31)
at Generator.next (<anonymous>)
at .../node_modules/casbin-sequelize-adapter/lib/adapter.js:20:71
at new WrappedPromise (node_modules/async-listener/es6-wrapped-promise.js:13:18)
at __awaiter (node_modules/casbin-sequelize-adapter/lib/adapter.js:16:12)
at SequelizeAdapter.addPolicy (node_modules/casbin-sequelize-adapter/lib/adapter.js:174:16)
at Context.<anonymous> (test/controller/attachment_controller_test.js:73:27)
Hello,
When I want to delete a user using deleteUser()
function, the user is deleted from the memory, but the change is not being saved to the DB. I need to call savePolicy()
afterward to do so.
Noting that addRoleForUser()
save automatically the changes to DB.
Can you help with this?
Thank you.
I believe this is a bug. When calling removeFilteredNamedPolicy
, sec
or ptype
values aren't respected.
Example
table content
id, ptype, v0, v1, v2, ...
1, p, user:1, table, read
2, p, user:1, desk, read
3, g, user:1, role:admin
4, p, user:2, desk, delete
enforcer.removeFilteredNamedPolicy('p', 0, 'user:1')
To remove rows 1,2. i.e. policies that are applied to a user
Removes rows 1,2 and 3. i.e. also removes grouping policies for user:1
async function init(mode){
let adapter = await SequelizeAdapter.newAdapter(`mysql://${mysql_user}:${mysql_password}@${mysql_host}:${mysql_port}/${mode}_casbin`,true);
let enforcer = await Enforcer.newEnforcer(
`${conf_uri}/${mode}.conf`,
adapter
);
await enforcer.loadPolicy();
return enforcer;
}
after init,set enforcer connecting in memory,
after init twice,use connecting in memory and two connecting only load one side policys.
Assigned to @zhmushan
Hi, I have just started integrating casbin into my saas multi tenant app for authorization management. I am building REST APIs which can be used by app's frontend roles and permission management module.
For this I have create multiple apis:-
....
async function returnEnforcer () {
const a = await SequelizeAdapter.newAdapter({
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
dialect: 'mysql',
dialectOptions: {
socketPath: `${dbSocketPath}/${process.env.INSTANCE_CONNECTION_NAME}`
}
})
const e = await casbin.newEnforcer('rbac_model.conf', a)
return e
}
class Casbin {
async addPolicies (rules) {
// Check the permission.
// Modify the policy.
// await e.addPolicy(...);
// await e.removePolicy(...);
const e = await returnEnforcer()
const added = await e.addNamedPolicies('p', rules)
return added
// Save the policy back to DB.
// await e.savePolicy();
}
async removePolicies (rules) {
const e = await returnEnforcer()
const removed = await e.removeNamedPolicies('p', rules)
return removed
}
async getPolicy (clientProjectFilter = null) {
const e = await returnEnforcer()
const policy = await e.getPolicy()
return policy
}
async enforce (request) {
const e = await returnEnforcer()
return e.enforce(request.sub, request.dom, request.obj, request.act)
}
**Issue with this is that it creates a new connection each time i call above functions from respective APIs, but somehow i need to understand if i can use my global connection pool already created for other modules as well. Or atleast a pool can be created dedicated for casbin interaction with mysql.
Please let me know if i am thinking on the correct lines and if above is possible then how can i achieve the connection pool so that i can optimize my connections with sql
Adapter now send logs to standard output and I cannot disable them. As it is usual in Sequelize and Casbin, I would like to be able to turn it off - or, preferably to send log messages to a customized log engine like Winston to provide logs which are properly leveled and customized, fitting my current logging system.
Hello,
Can I remove or ignore the 'id' column of created casbin_rule table?
If so, where shall I edit? Since I don't see the 'id' field in your model.
Thanks.
how long to start support v6
Need to update this repo to use a newer Sequalize to remove the vulnerability in Sequalize < v6.19.1. I tried but running into some problems with #69, any help would be great!
Using sequelize-adapter
with CommonJS module complains about sequelize object being undefined.
Here is the stack trace:
/Repos/config-service/node_modules/sequelize/lib/model.js:55
return this.sequelize.getQueryInterface();
^
TypeError: Cannot read property 'getQueryInterface' of undefined
at Function.get queryInterface [as queryInterface] (/Repos/config-service/node_modules/sequelize/lib/model.js:55:27)
at isFunctionMember (/Repos/config-service/node_modules/sequelize-typescript/dist/model/model/model.js:99:25)
at object_1.getAllPropertyNames.filter.key (/Repos/config-service/node_modules/sequelize-typescript/dist/model/model/model.js:96:5)
at Array.filter (<anonymous>)
at Object.<anonymous> (/Repos/config-service/node_modules/sequelize-typescript/dist/model/model/model.js:95:6)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
Here is the code being run:
const casbin = require("casbin");
const { SequelizeAdapter } = require("casbin-sequelize-adapter");
(async () => {
const a = await SequelizeAdapter.newAdapter({
host: "localhost",
port: "3306",
username: "root",
password: "",
database: "test",
dialect: "mysql",
});
const e = await casbin.newEnforcer("../model.conf", a);
e.enforce("alice", "data1", "read");
})();
node version: v14.8.0
"casbin": "^5.1.3",
"casbin-sequelize-adapter": "^2.1.0",
See: #61 (comment)
So i ran this in java
enforcer.addPolicy("abcd","123","read");
This creates a table casbin_rule
which is fine with columns
ptype,v0,v1,v2,v3,v4,v5
But now i connect the same database with NodeJS with casbin-sequelize-adapter
const casbin = require('casbin');
const { SequelizeAdapter } = require('casbin-sequelize-adapter');
(async () => {
const a = await SequelizeAdapter.newAdapter({
host: 'localhost',
port: '3306',
username: 'root',
password: 'root',
database: 'myhiber',
dialect: 'mysql',
});
const e = await casbin.newEnforcer('../model.conf', a);
// Check the permission.
console.log(e.enforce('abcd', '123', 'read'))
})()
But it is throwing an error
Executing (default): SELECT 1+1 AS result
Executing (default): CREATE TABLE IF NOT EXISTS `casbin_rule` (`id` INTEGER NOT NULL auto_increment , `ptype` VARCHAR(255), `v0` VARCHAR(255), `v1` VARCHAR(255), `v2` VARCHAR(255), `v3` VARCHAR(255), `v4` VARCHAR(255), `v5` VARCHAR(255), PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `casbin_rule` FROM `myhiber`
Executing (default): SELECT `id`, `ptype`, `v0`, `v1`, `v2`, `v3`, `v4`, `v5` FROM `casbin_rule` AS `CasbinRule`;
(node:6328) UnhandledPromiseRejectionWarning: SequelizeDatabaseError: Unknown column 'id' in 'field list'
Why is it trying to select a different schema structure in default compared to Java ? hence the error log ..
Selecting id
is the issue here
When using a postgres URI for creating a new sequelize adapter I'm getting SSL connection is required. Please specify SSL options and retry.
.
Below is the syntax I'm using.
const { SequelizeAdapter } = require("casbin-sequelize-adapter");
sqladapter = await SequelizeAdapter.newAdapter(postgres://root@localhost:5432/testdb, {
dialect: "postgres",
schema: "automation",
dialectOptions: {
ssl: true,
},
});
The adapter works fine when using username, password syntax.
sqladapter = await SequelizeAdapter.newAdapter({
host: "hostname",
port: "5432",
username: "root",
password: "",
database: "testdb",
dialect: "postgres",
schema: "automation",
dialectOptions: {
ssl: true,
},
});
"sequelize": "^5.22.3"
"casbin-sequelize-adapter": "^2.1.0"
"casbin": "^5.1.3"
Setting logging: false
fails to prevent query logs output to console. This is inconsistent with base node-casbin.
This disables logging
const sequelize = new Sequelize(
dbUrl(),
{
logging: false,
dialect: 'postgres',
dialectOptions: dialectOptions
}
);
This does not
const a = await SequelizeAdapter.newAdapter(
dbUrl(),
{
logging: false,
dialect: 'postgres',
dialectOptions: dialectOptions
}
);
Otherwise, either connection works.
I'm using sequelize adapter for creating a persistent implementation of my ACL. As I said in this issue #19 I'm loading from file all the default policy that my system must have. I've noticed that after I've loaded all the infos I need in Caspin and then I call savePolicy
in the Postrgre database all the entities get duplicated. This is supposed to work like that with the Auto-Save?
I am using nestjs. What would be the best practice for implementation? I don't want to create a new instance of this every time it is used?
Gina
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.