blob: a86f11037c3c0cc52db9c9cceba5d2eacf68956a [file]
// Copyright 2018 The Casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {Adapter, Helper, Model} from 'casbin';
import {Sequelize, SequelizeOptions} from 'sequelize-typescript';
import {CasbinRule} from './casbinRule';
/**
* SequelizeAdapter represents the Sequelize adapter for policy storage.
*/
export class SequelizeAdapter implements Adapter {
private option: SequelizeOptions;
private sequelize: Sequelize;
constructor(option: SequelizeOptions) {
this.option = option;
}
/**
* newAdapter is the constructor.
* @param option sequelize connection option
*/
public static async newAdapter(option: SequelizeOptions) {
const a = new SequelizeAdapter(option);
await a.open();
return a;
}
private async open() {
this.sequelize = new Sequelize(this.option);
await this.sequelize.authenticate();
this.sequelize.addModels([CasbinRule]);
await this.createTable();
}
public async close() {
await this.sequelize.close();
}
private async createTable() {
await this.sequelize.sync();
}
private async dropTable() {
await this.sequelize.getRepository(CasbinRule).destroy({where: {}, truncate: true});
}
private loadPolicyLine(line: CasbinRule, model: Model) {
const result = line.ptype + ', ' + [line.v0, line.v1, line.v2, line.v3, line.v4, line.v5].filter(n => n).join(', ');
Helper.loadPolicyLine(result, model);
}
/**
* loadPolicy loads all policy rules from the storage.
*/
public async loadPolicy(model: Model) {
const lines = await this.sequelize.getRepository(CasbinRule).findAll();
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;
}
/**
* savePolicy saves all policy rules to the storage.
*/
public async savePolicy(model: Model) {
await this.dropTable();
await this.createTable();
let astMap = model.model.get('p')!;
for (const [ptype, ast] of astMap) {
for (const rule of ast.policy) {
const line = this.savePolicyLine(ptype, rule);
await line.save();
}
}
astMap = model.model.get('g')!;
for (const [ptype, ast] of astMap) {
for (const rule of ast.policy) {
const line = this.savePolicyLine(ptype, rule);
await line.save();
}
}
return true;
}
/**
* addPolicy adds a policy rule to the storage.
*/
public async addPolicy(sec: string, ptype: string, rule: string[]) {
const line = this.savePolicyLine(ptype, rule);
await line.save();
}
/**
* removePolicy removes a policy rule from the storage.
*/
public async removePolicy(sec: string, ptype: string, rule: string[]) {
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.getRepository(CasbinRule).destroy({where});
}
/**
* removeFilteredPolicy removes policy rules that match the filter from the storage.
*/
public async removeFilteredPolicy(sec: string, ptype: string, fieldIndex: number, ...fieldValues: string[]) {
throw new Error('not implemented');
}
}