Sequelize v6 compatibility: addPolicies & removePolicies problem
Closed this issue · 13 comments
My database has a row
row1. ['userA', 'product', 'read']
I want to run function
addPolicies(
['userA', 'product', 'read'],
['userA', 'product', 'write']
)
I think the result should be
row1. ['userA', 'product', 'read']
row2. ['userA', 'product', 'write']
or
removePolicies(
['userA', 'product', 'read'],
['userA', 'product', 'write']
)
I think the result should be
no rows.
They're all return false
and database is not been effect
Is it intentional?
We need to resolve: node-casbin/sequelize-adapter#34 first
@nodece
I am using sequelize-adapter,
But its not support v6, your team is upgrading,
so, I copy sequelize-adapter source code to make it running.
Then, this problem is shown.
When you upgraded, I will change to use sequelize-adapter.
I'm not sure this problem has appear node-casbin or sequelize-adapter
adapter.ts
import { Adapter, Helper, Model } from 'casbin';
import { Sequelize, Options } from 'sequelize'
import { CasbinRule, CasbinRuleSchema } from './CasbinRule';
export class SequelizeAdapter implements Adapter {
private option: Options;
private sequelize!: Sequelize;
constructor(option: Options) {
this.option = option;
}
public static async newAdapter(option: Options): Promise<SequelizeAdapter> {
const a = new SequelizeAdapter(option);
await a.open();
return a;
}
private async open(): Promise<void> {
this.sequelize = new Sequelize(this.option);
await this.sequelize.authenticate();
CasbinRule.init(CasbinRuleSchema, { tableName: 'casbin_rule', sequelize: this.sequelize, freezeTableName: true })
await this.createTable();
}
public async close(): Promise<void> {
await this.sequelize.close();
}
private async createTable(): Promise<void> {
await this.sequelize.sync();
}
private loadPolicyLine(line: CasbinRule, model: Model): void {
const result = line.ptype + ', ' +
[line.v0, line.v1, line.v2, line.v3, line.v4, line.v5].filter((n) => n).join(', ');
Helper.loadPolicyLine(result, model);
}
public async loadPolicy(model: Model): Promise<void> {
const lines = await this.sequelize.model('CasbinRule').findAll() as Array<CasbinRule>;
for (const line of lines) {
this.loadPolicyLine(line, model);
}
}
private savePolicyLine(ptype: string, rule: string[]): CasbinRule {
const line = new CasbinRule();
line.ptype = ptype;
if (rule.length > 0) line.v0 = rule[0];
if (rule.length > 1) line.v1 = rule[1];
if (rule.length > 2) line.v2 = rule[2];
if (rule.length > 3) line.v3 = rule[3];
if (rule.length > 4) line.v4 = rule[4];
if (rule.length > 5) line.v5 = rule[5];
return line;
}
public async savePolicy(model: Model): Promise<boolean> {
await this.sequelize.transaction(async (tx) => {
await this.sequelize.model('CasbinRule').destroy({ where: {}, truncate: true, transaction: tx });
const lines: CasbinRule[] = [];
['p', 'g'].forEach((e) => {
const astMap = model.model.get(e)!;
for (const [ptype, ast] of astMap) {
for (const rule of ast.policy) {
const line = this.savePolicyLine(ptype, rule);
lines.push(line);
}
}
});
await CasbinRule.bulkCreate(
lines.map((l) => l.get({ plain: true })), { transaction: tx }
)
})
return true;
}
public async addPolicy(
sec: string,
ptype: string,
rule: string[]
) {
const line = this.savePolicyLine(ptype, rule);
await line.save();
}
public async addPolicies(sec: string, ptype: string, rules: string[][]): Promise<void> {
const lines: CasbinRule[] = [];
for (const rule of rules) {
const line = this.savePolicyLine(ptype, rule);
lines.push(line);
}
await this.sequelize.transaction(async (tx) => {
await CasbinRule.bulkCreate(
lines.map((l) => l.get({ plain: true })), { transaction: tx }
);
});
}
public async removePolicy(sec: string, ptype: string, rule: string[],): Promise<void> {
const line = this.savePolicyLine(ptype, rule);
const where = {};
Object.keys(line.get({ plain: true }))
.filter((key) => key !== 'id')
.forEach((key) => {
// @ts-ignore
where[key] = line[key];
})
await this.sequelize.model('CasbinRule').destroy({ where });
}
public async removePolicies(sec: string, ptype: string, rules: string[][]): Promise<void> {
await this.sequelize.transaction(async (tx) => {
for (const rule of rules) {
const line = this.savePolicyLine(ptype, rule);
const where = {};
Object.keys(line.get({ plain: true }))
.filter((key) => key !== 'id')
.forEach((key) => {
// @ts-ignore
where[key] = line[key];
})
await this.sequelize.model('CasbinRule').destroy({ where, transaction: tx });
}
})
}
public async removeFilteredPolicy(sec: string, ptype: string, fieldIndex: number, ...fieldValues: string[]): Promise<void> {
const line = new CasbinRule();
const idx = fieldIndex + fieldValues.length;
if (fieldIndex <= 0 && 0 < idx) line.v0 = fieldValues[0 - fieldIndex];
if (fieldIndex <= 1 && 1 < idx) line.v1 = fieldValues[1 - fieldIndex];
if (fieldIndex <= 2 && 2 < idx) line.v2 = fieldValues[2 - fieldIndex];
if (fieldIndex <= 3 && 3 < idx) line.v3 = fieldValues[3 - fieldIndex];
if (fieldIndex <= 4 && 4 < idx) line.v4 = fieldValues[4 - fieldIndex];
if (fieldIndex <= 5 && 5 < idx) line.v5 = fieldValues[5 - fieldIndex];
const where = {};
Object.keys(line.get({ plain: true }))
.filter((key) => key !== 'id')
.forEach((key) => {
// @ts-ignore
where[key] = line[key]
})
await this.sequelize.model('CasbinRule').destroy({ where })
}
}
casbinRule.ts
import { DataTypes, Model, Optional, ModelAttributes } from 'sequelize';
interface CasbinRuleAttributes {
ptype: string;
v0: string;
v1: string;
v2: string;
v3: string;
v4: string;
v5: string;
}
interface CasbinRuleCreationAttributes extends Optional<CasbinRuleAttributes, 'ptype'> { }
export class CasbinRule extends Model<CasbinRuleAttributes, CasbinRuleCreationAttributes> implements CasbinRuleAttributes {
public ptype!: string;
public v0!: string;
public v1!: string;
public v2!: string;
public v3!: string;
public v4!: string;
public v5!: string;
}
export const CasbinRuleSchema: ModelAttributes = {
ptype: {
type: DataTypes.STRING,
},
v0: {
type: DataTypes.STRING,
},
v1: {
type: DataTypes.STRING,
},
v2: {
type: DataTypes.STRING,
},
v3: {
type: DataTypes.STRING,
},
v4: {
type: DataTypes.STRING,
},
v5: {
type: DataTypes.STRING,
},
}
export default CasbinRule;
We can try latest sequelize-typescript 2.0.0-beta.1 (a month ago) with sequelize >=6.2, see: sequelize/sequelize-typescript#856
@hsluoyz Is there any guide for setup of code on local machine and any contribution.md as I am not getting hang of the code
Acc to me I have to fix the function addPolicies at https://github.com/casbin/node-casbin/blob/master/src/model/model.ts
We can try latest sequelize-typescript 2.0.0-beta.1 (a month ago) with sequelize >=6.2, see: RobinBuschmann/sequelize-typescript#856
@nodece , @hsluoyz I have made the changes mentioned in this comment , @fish0373 can you please tell me how to recreate this error on my local machine so that I can check if this fixed it.
@Yash-g17 @PrashubhAtri please resolve: node-casbin/sequelize-adapter#34 first
@hsluoyz @nodece resolved the issue mentioned above ,
Working on this one.
@Yash-g17 not yet. See: node-casbin/sequelize-adapter#39 (comment)
@fish0373 Sequelize v6 is supported in latest casbin-sequelize-adapter v2.2.0: https://www.npmjs.com/package/casbin-sequelize-adapter/v/2.2.0
Plz try again.