Skip to content

Commit

Permalink
feat: add support for in operator
Browse files Browse the repository at this point in the history
Signed-off-by: Zxilly <zhouxinyu1001@gmail.com>
  • Loading branch information
Zxilly committed Jun 13, 2021
1 parent 839dbff commit a44c6a9
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 8 deletions.
11 changes: 11 additions & 0 deletions examples/in_operator_model.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[request_definition]
r = sub, obj

[policy_definition]
p = sub, obj, act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.sub.Owner == r.obj.Owner && r.sub.Doc in(r.obj.Docs)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"dependencies": {
"await-lock": "^2.0.1",
"csv-parse": "^4.15.3",
"expression-eval": "^2.0.0",
"expression-eval": "^4.0.0",
"picomatch": "^2.2.3"
},
"files": [
Expand Down
8 changes: 7 additions & 1 deletion src/coreEnforcer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { compile, compileAsync } from 'expression-eval';
import { compile, compileAsync, addBinaryOp } from 'expression-eval';

import { DefaultEffector, Effect, Effector } from './effect';
import { FunctionMap, Model, newModel, PolicyOp } from './model';
Expand Down Expand Up @@ -48,6 +48,12 @@ export class CoreEnforcer {
private getExpression(asyncCompile: boolean, exp: string): Matcher {
const matcherKey = `${asyncCompile ? 'ASYNC[' : 'SYNC['}${exp}]`;

addBinaryOp('in', 1, (a, b) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return (a in b) as number;
});

let expression = this.matcherMap.get(matcherKey);
if (!expression) {
expression = asyncCompile ? compileAsync(exp) : compile(exp);
Expand Down
5 changes: 3 additions & 2 deletions test/frontend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// limitations under the License.

import { readFileSync } from 'fs';
import { newEnforcer } from '../src/index';
import { casbinJsGetPermissionForUser } from '../src/frontend';
import { newEnforcer } from '../src';
import { casbinJsGetPermissionForUser } from '../src';

test('TestCasbinJsGetPermissionForUser', async () => {
const e = await newEnforcer('examples/rbac_model.conf', 'examples/rbac_with_hierarchy_policy.csv');
Expand All @@ -25,6 +25,7 @@ test('TestCasbinJsGetPermissionForUser', async () => {
}
const received = JSON.parse(await casbinJsGetPermissionForUser(e, 'alice'));
const expectedModelStr = readFileSync('examples/rbac_model.conf').toString();
// If you enable CR_LF auto transfer on Windows platform, this can lead to some unexpected behavior.
expect(received['m']).toBe(expectedModelStr.replace(/\n\n/g, '\n'));
const expectedPoliciesStr = readFileSync('examples/rbac_with_hierarchy_policy.csv').toString();
const expectedPolicyItem = expectedPoliciesStr.split(RegExp(',|\n'));
Expand Down
30 changes: 30 additions & 0 deletions test/model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// 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.
// noinspection JSMismatchedCollectionQueryUpdate

import * as _ from 'lodash';
import { DefaultRoleManager, Enforcer, newEnforcer, newModel } from '../src';
Expand Down Expand Up @@ -418,3 +419,32 @@ test('TestAllMatchModel', async () => {
await testDomainEnforce(e, 'alice', 'domain2', '/book/1', 'read', false);
await testDomainEnforce(e, 'alice', 'domain2', '/book/1', 'write', true);
});

test('ABACModelWithInOperator', async () => {
const e = await newEnforcer('examples/in_operator_model.conf');

class TestRule1 {
public Owner: string;
public Doc: number;

constructor(Owner: string, Doc: number) {
this.Owner = Owner;
this.Doc = Doc;
}
}

class TestRule2 {
public Owner: string;
public Docs: Array<number>;

constructor(Owner: string, Doc: Array<number>) {
this.Owner = Owner;
this.Docs = Doc;
}
}

const rule1 = new TestRule1('alice', 1);
const rule2 = new TestRule2('alice', [1, 2]);

await expect(e.enforce(rule1, rule2)).resolves.toBe(true);
});
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2828,10 +2828,10 @@ expect@^26.6.2:
jest-message-util "^26.6.2"
jest-regex-util "^26.0.0"

expression-eval@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/expression-eval/-/expression-eval-2.1.0.tgz#422915caa46140a7c5b5f248650dea8bf8236e62"
integrity sha512-FUJO/Akvl/JOWkvlqZaqbkhsEWlCJWDeZG4tzX96UH68D9FeRgYgtb55C2qtqbORC0Q6x5419EDjWu4IT9kQfg==
expression-eval@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/expression-eval/-/expression-eval-4.0.0.tgz#d6a07c93e8b33e635710419d4a595d9208b9cc5e"
integrity sha512-YHSnLTyIb9IKaho2IdQbvlei/pElxnGm48UgaXJ1Fe5au95Ck0R9ftm6rHJQuKw3FguZZ4eXVllJFFFc7LX0WQ==
dependencies:
jsep "^0.3.0"

Expand Down

0 comments on commit a44c6a9

Please sign in to comment.