casbin
Version:
An authorization library that supports access control models like ACL, RBAC, ABAC in Node.JS
173 lines (172 loc) • 5.45 kB
JavaScript
// 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 { readFileSync } from 'fs';
export class Config {
constructor() {
this.data = new Map();
}
/**
* newConfig create an empty configuration representation from file.
*
* @param confName the path of the model file.
* @return the constructor of Config.
*/
static newConfig(confName) {
const config = new Config();
config.parse(confName);
return config;
}
/**
* newConfigFromText create an empty configuration representation from text.
*
* @param text the model text.
* @return the constructor of Config.
*/
static newConfigFromText(text) {
const config = new Config();
config.parseBuffer(Buffer.from(text));
return config;
}
/**
* addConfig adds a new section->key:value to the configuration.
*/
addConfig(section, option, value) {
if (section === '') {
section = Config.DEFAULT_SECTION;
}
const hasKey = this.data.has(section);
if (!hasKey) {
this.data.set(section, new Map());
}
const item = this.data.get(section);
if (item) {
item.set(option, value);
return item.has(option);
}
else {
return false;
}
}
parse(path) {
const buf = readFileSync(path);
this.parseBuffer(buf);
}
parseBuffer(buf) {
const lines = buf.toString().split('\n');
const linesCount = lines.length;
let section = '';
let currentLine = '';
lines.forEach((n, index) => {
let commentPos = n.indexOf(Config.DEFAULT_COMMENT);
if (commentPos > -1) {
n = n.slice(0, commentPos);
}
commentPos = n.indexOf(Config.DEFAULT_COMMENT_SEM);
if (commentPos > -1) {
n = n.slice(0, commentPos);
}
const line = n.trim();
if (!line) {
return;
}
const lineNumber = index + 1;
if (line.startsWith('[') && line.endsWith(']')) {
if (currentLine.length !== 0) {
this.write(section, lineNumber - 1, currentLine);
currentLine = '';
}
section = line.substring(1, line.length - 1);
}
else {
let shouldWrite = false;
if (line.includes(Config.DEFAULT_MULTI_LINE_SEPARATOR)) {
currentLine += line.substring(0, line.length - 1).trim();
// when the last line has a "\" string
if (lineNumber + 1 === linesCount) {
shouldWrite = true;
}
}
else {
currentLine += line;
shouldWrite = true;
}
if (shouldWrite) {
this.write(section, lineNumber, currentLine);
currentLine = '';
}
}
});
}
write(section, lineNum, line) {
const equalIndex = line.indexOf('=');
if (equalIndex === -1) {
throw new Error(`parse the content error : line ${lineNum}`);
}
const key = line.substring(0, equalIndex);
const value = line.substring(equalIndex + 1);
this.addConfig(section, key.trim(), value.trim());
}
getBool(key) {
return !!this.get(key);
}
getInt(key) {
return Number.parseInt(this.get(key), 10);
}
getFloat(key) {
return Number.parseFloat(this.get(key));
}
getString(key) {
return this.get(key);
}
getStrings(key) {
const v = this.get(key);
return v.split(',');
}
set(key, value) {
if (!key) {
throw new Error('key is empty');
}
let section = '';
let option;
const keys = key.toLowerCase().split('::');
if (keys.length >= 2) {
section = keys[0];
option = keys[1];
}
else {
option = keys[0];
}
this.addConfig(section, option, value);
}
get(key) {
let section;
let option;
const keys = key.toLowerCase().split('::');
if (keys.length >= 2) {
section = keys[0];
option = keys[1];
}
else {
section = Config.DEFAULT_SECTION;
option = keys[0];
}
const item = this.data.get(section);
const itemChild = item && item.get(option);
return itemChild ? itemChild : '';
}
}
Config.DEFAULT_SECTION = 'default';
Config.DEFAULT_COMMENT = '#';
Config.DEFAULT_COMMENT_SEM = ';';
Config.DEFAULT_MULTI_LINE_SEPARATOR = '\\';