diff --git a/examples/rbac_policy.csv b/examples/rbac_policy.csv index 4150272..8479f3c 100644 --- a/examples/rbac_policy.csv +++ b/examples/rbac_policy.csv @@ -2,5 +2,4 @@ p, alice, data1, read p, bob, data2, write p, data2_admin, data2, read p, data2_admin, data2, write - g, alice, data2_admin diff --git a/src/config.ts b/src/config.ts index 2c6f51d..4d3664c 100644 --- a/src/config.ts +++ b/src/config.ts @@ -17,10 +17,11 @@ export class Config { private static DEFAULT_SECTION = 'default'; private static DEFAULT_COMMENT = '#'; private static DEFAULT_COMMENT_SEM = ';'; + private static DEFAULT_MULTI_LINE_SEPARATOR = '\\'; private data: Map>; - constructor() { + private constructor() { this.data = new Map>(); } @@ -75,33 +76,56 @@ export class Config { } private parseBuffer(buf: Buffer): void { - let section = ''; const lines = buf.toString().split('\n'); + const linesCount = lines.length; + let section = ''; + let currentLine = ''; lines.forEach((n, index) => { const line = n.trim(); + const lineNumber = index + 1; if (!line) { return; } - if (line.startsWith(Config.DEFAULT_COMMENT)) { - return; - } else if (line.startsWith(Config.DEFAULT_COMMENT_SEM)) { + if (line.startsWith(Config.DEFAULT_COMMENT) || line.startsWith(Config.DEFAULT_COMMENT_SEM)) { return; } else if (line.startsWith('[') && line.endsWith(']')) { + if (currentLine.length !== 0) { + this.write(section, lineNumber - 1, currentLine); + currentLine = ''; + } section = line.substring(1, line.length - 1); } else { - const equalIndex = line.indexOf('='); - if (equalIndex === -1) { - throw new Error(`parse the content error : line ${index + 1}`); + 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 = ''; } - const key = line.substring(0, equalIndex); - const value = line.substring(equalIndex + 1); - this.addConfig(section, key.trim(), value.trim()); } }); } + private write(section: string, lineNum: number, line: string) { + 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()); + } + public getBool(key: string): boolean { return !!this.get(key); } diff --git a/src/index.ts b/src/index.ts index f90187e..83079b7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ import * as Util from './util'; +export * from './config'; export * from './enforcer'; export * from './effect'; export * from './model'; diff --git a/test/config/config.test.ts b/test/config/config.test.ts new file mode 100644 index 0000000..5c84652 --- /dev/null +++ b/test/config/config.test.ts @@ -0,0 +1,25 @@ +import { Config } from '../../src'; + +const config = Config.newConfig('test/config/testini.ini'); + +describe('multi-line test', () => { + it('should config.get("multi1::name") to equal r.sub==p.sub&&r.obj==p.obj', function() { + expect(config.get('multi1::name')).toEqual('r.sub==p.sub&&r.obj==p.obj'); + }); + + it('should config.get("multi2::name") to equal r.sub==p.sub&&r.obj==p.obj', function() { + expect(config.get('multi2::name')).toEqual('r.sub==p.sub&&r.obj==p.obj'); + }); + + it('should config.get("multi3::name") to equal r.sub==p.sub&&r.obj==p.obj', function() { + expect(config.get('multi3::name')).toEqual('r.sub==p.sub&&r.obj==p.obj'); + }); + + it('should config.get("multi4::name") to equal r.sub==p.sub&&r.obj==p.obj', function() { + expect(config.get('multi4::name')).toEqual(''); + }); + + it('should config.get("multi5::name") to equal r.sub==p.sub&&r.obj==p.obj', function() { + expect(config.get('multi5::name')).toEqual('r.sub==p.sub&&r.obj==p.obj'); + }); +}); diff --git a/test/config/testini.ini b/test/config/testini.ini new file mode 100644 index 0000000..59a6987 --- /dev/null +++ b/test/config/testini.ini @@ -0,0 +1,47 @@ +# test config +debug = true +url = act.wiki + +; redis config +[redis] +redis.key = push1,push2 + +; mysql config +[mysql] +mysql.dev.host = 127.0.0.1 +mysql.dev.user = root +mysql.dev.pass = 123456 +mysql.dev.db = test + +mysql.master.host = 10.0.0.1 +mysql.master.user = root +mysql.master.pass = 89dds)2$#d +mysql.master.db = act + +; math config +[math] +math.i64 = 64 +math.f64 = 64.1 + +# multi-line test +[multi1] +name = r.sub==p.sub \ + &&r.obj==p.obj\ + \ +[multi2] +name = r.sub==p.sub \ + &&r.obj==p.obj + +[multi3] +name = r.sub==p.sub \ + &&r.obj==p.obj + +[multi4] +name = \ +\ + \ + +[multi5] +name = r.sub==p.sub \ + &&r.obj==p.obj\ + \