Skip to content

Commit

Permalink
Merge c653e8c into 7758d43
Browse files Browse the repository at this point in the history
  • Loading branch information
nodece committed Aug 11, 2018
2 parents 7758d43 + c653e8c commit 666fe23
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 101 deletions.
92 changes: 48 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,66 @@
node-casbin
====

[![NPM version][npm-image]][npm-url]
[![NPM download][download-image]][download-url]
[![codebeat badge](https://codebeat.co/badges/c17c9ee1-da42-4db3-8047-9574ad2b23b1)](https://codebeat.co/projects/github-com-casbin-node-casbin-master)
[![Build Status](https://travis-ci.org/casbin/node-casbin.svg?branch=master)](https://travis-ci.org/casbin/node-casbin)
[![Coverage Status](https://coveralls.io/repos/github/casbin/node-casbin/badge.svg?branch=master)](https://coveralls.io/github/casbin/node-casbin?branch=master)
[![Release](https://img.shields.io/github/release/casbin/node-casbin.svg)](https://github.com/casbin/node-casbin/releases/latest)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/casbin/lobby)
[![Patreon](https://img.shields.io/badge/patreon-donate-yellow.svg)](http://www.patreon.com/yangluo)
[![Sourcegraph Badge](https://sourcegraph.com/github.com/casbin/casbin/-/badge.svg)](https://sourcegraph.com/github.com/casbin/casbin?badge)
[![Sourcegraph Badge](https://sourcegraph.com/github.com/casbin/node-casbin/-/badge.svg)](https://sourcegraph.com/github.com/casbin/node-casbin?badge)

[npm-image]: https://img.shields.io/npm/v/casbin.svg?style=flat-square
[npm-url]: https://npmjs.org/package/casbin
[download-image]: https://img.shields.io/npm/dm/casbin.svg?style=flat-square
[download-url]: https://npmjs.org/package/casbin

**News**: still worry about how to write the correct node-casbin policy? ``Casbin online editor`` is coming to help! Try it at: http://casbin.org/editor/

![casbin Logo](casbin-logo.png)

node-casbin is a powerful and efficient open-source access control library for Node.JS projects. It provides support for enforcing authorization based on various [access control models](https://en.wikipedia.org/wiki/Computer_security_model).

## Installation

```
npm install casbin --save
```

## Get started

1. New a node-casbin enforcer with a model file and a policy file:

```typescript
const enforcer = await Enforcer.newEnforcer('path/to/model.conf', 'path/to/policy.csv');
```

Note: you can also initialize an enforcer with policy in DB instead of file, see [Persistence](#persistence) section for details.

2. Add an enforcement hook into your code right before the access happens:

```typescript
const sub = 'alice'; // the user that wants to access a resource.
const obj = 'data1'; // the resource that is going to be accessed.
const act = 'read'; // the operation that the user performs on the resource.

if (enforcer.enforce(sub, obj, act) == true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
```

3. Besides the static policy file, node-casbin also provides API for permission management at run-time. For example, You can get all the roles assigned to a user as below:

```typescript
const roles = enforcer.getRoles('alice');
```

See [Policy management APIs](#policy-management) for more usage.

4. Please refer to the [src/test](https://github.com/casbin/node-casbin/tree/master/test) package for more usage.

## All the languages supported by Casbin:

- Golang: [Casbin](https://github.com/casbin/casbin) (production-ready)
Expand All @@ -28,11 +74,9 @@ node-casbin is a powerful and efficient open-source access control library for N
- [Supported models](#supported-models)
- [How it works?](#how-it-works)
- [Features](#features)
- [Installation](#installation)
- [Documentation](#documentation)
- [Online editor](#online-editor)
- [Tutorials](#tutorials)
- [Get started](#get-started)
- [Policy management](#policy-management)
- [Policy persistence](#policy-persistence)
- [Role manager](#role-manager)
Expand Down Expand Up @@ -104,12 +148,6 @@ What node-casbin does NOT do:
1. authentication (aka verify ``username`` and ``password`` when a user logs in)
2. manage the list of users or roles. I believe it's more convenient for the project itself to manage these entities. Users usually have their passwords, and node-casbin is not designed as a password container. However, node-casbin stores the user-role mapping for the RBAC scenario.

## Installation

```
npm install casbin
```

## Documentation

For documentation, please see: [Our Wiki](https://github.com/casbin/casbin/wiki)
Expand All @@ -125,40 +163,6 @@ You can also use the online editor (http://casbin.org/editor/) to write your nod
- [Using Casbin with Beego: 2. Policy storage (in Chinese)](http://blog.csdn.net/hotqin888/article/details/78571240)
- [Using Casbin with Beego: 3. Policy query (in Chinese)](http://blog.csdn.net/hotqin888/article/details/78992250)

## Get started

1. New a node-casbin enforcer with a model file and a policy file:

```typescript
const enforcer = new Enforcer('path/to/model.conf', 'path/to/policy.csv');
```

Note: you can also initialize an enforcer with policy in DB instead of file, see [Persistence](#persistence) section for details.

2. Add an enforcement hook into your code right before the access happens:

```typescript
const sub = 'alice'; // the user that wants to access a resource.
const obj = 'data1'; // the resource that is going to be accessed.
const act = 'read'; // the operation that the user performs on the resource.

if (enforcer.enforce(sub, obj, act) == true) {
// permit alice to read data1
} else {
// deny the request, show an error
}
```

3. Besides the static policy file, node-casbin also provides API for permission management at run-time. For example, You can get all the roles assigned to a user as below:

```typescript
const roles = enforcer.getRoles('alice');
```

See [Policy management APIs](#policy-management) for more usage.

4. Please refer to the [src/test](https://github.com/casbin/node-casbin/tree/master/test) package for more usage.

## Policy management

node-casbin provides two sets of APIs to manage permissions:
Expand Down
44 changes: 24 additions & 20 deletions src/enforcer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ export class Enforcer {
private autoBuildRoleLinks: boolean;

/**
* constructor is the constructor for Enforcer.
* It creates an enforcer via file or DB.
* newEnforcer creates an enforcer via file or DB.
*
* File:
* ```js
Expand All @@ -56,9 +55,10 @@ export class Enforcer {
*
* @param params
*/
constructor(...params: any[]) {
this.rm = new DefaultRoleManager(10);
this.eft = new DefaultEffector();
public static async newEnforcer(...params: any[]): Promise<Enforcer> {
const e = new Enforcer();
e.rm = new DefaultRoleManager(10);
e.eft = new DefaultEffector();

let parsedParamLen = 0;
if (params.length >= 1) {
Expand All @@ -72,48 +72,49 @@ export class Enforcer {
if (params.length - parsedParamLen === 2) {
if (typeof params[0] === 'string') {
if (typeof params[1] === 'string') {
this.initWithFile(params[0].toString(), params[1].toString());
await e.initWithFile(params[0].toString(), params[1].toString());
} else {
this.initWithAdapter(params[0].toString(), params[1]);
await e.initWithAdapter(params[0].toString(), params[1]);
}
} else {
if (typeof params[1] === 'string') {
throw new Error('Invalid parameters for enforcer.');
} else {
this.initWithModelAndAdapter(params[0], params[1]);
await e.initWithModelAndAdapter(params[0], params[1]);
}
}
} else if (params.length - parsedParamLen === 1) {
if (typeof params[0] === 'string') {
this.initWithFile(params[0], '');
await e.initWithFile(params[0], '');
} else {
this.initWithModelAndAdapter(params[0], null);
await e.initWithModelAndAdapter(params[0], null);
}
} else if (params.length === parsedParamLen) {
this.initWithFile('', '');
await e.initWithFile('', '');
} else {
throw new Error('Invalid parameters for enforcer.');
}
return e;
}

/**
* initWithFile initializes an enforcer with a model file and a policy file.
* @param modelPath model file path
* @param policyPath policy file path
*/
public initWithFile(modelPath: string, policyPath: string): void {
public async initWithFile(modelPath: string, policyPath: string): Promise<void> {
const a = new FileAdapter(policyPath);
this.initWithAdapter(modelPath, a);
await this.initWithAdapter(modelPath, a);
}

/**
* initWithAdapter initializes an enforcer with a database adapter.
* @param modelPath model file path
* @param adapter current adapter instance
*/
public initWithAdapter(modelPath: string, adapter: Adapter): void {
public async initWithAdapter(modelPath: string, adapter: Adapter): Promise<void> {
const m = Enforcer.newModel(modelPath, '');
this.initWithModelAndAdapter(m, adapter);
await this.initWithModelAndAdapter(m, adapter);

this.modelPath = modelPath;
}
Expand All @@ -123,7 +124,7 @@ export class Enforcer {
* @param m model instance
* @param adapter current adapter instance
*/
public initWithModelAndAdapter(m: Model, adapter: Adapter | null): void {
public async initWithModelAndAdapter(m: Model, adapter: Adapter | null): Promise<void> {
if (adapter) {
this.adapter = adapter;
}
Expand All @@ -132,15 +133,18 @@ export class Enforcer {
this.model = m;
this.model.printModel();
this.fm = FunctionMap.loadFunctionMap();
this.initialize();

if (this.adapter) {
// error intentionally ignored
await this.loadPolicy();
}
}

public async initialize(): Promise<void> {
public initialize(): void {
this.enabled = true;
this.autoSave = true;
this.autoBuildRoleLinks = true;
if (this.adapter) {
await this.loadPolicy();
}
}

/**
Expand Down
9 changes: 3 additions & 6 deletions test/enforcer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ test('TestKeyMatchModelInMemory', async () => {

const a = new FileAdapter('examples/keymatch_policy.csv');

let e = new Enforcer(m, a);
await e.initialize();
let e = await Enforcer.newEnforcer(m, a);

testEnforce(e, 'alice', '/alice_data/resource1', 'GET', true);
testEnforce(e, 'alice', '/alice_data/resource1', 'POST', true);
Expand All @@ -53,8 +52,7 @@ test('TestKeyMatchModelInMemory', async () => {
testEnforce(e, 'cathy', '/cathy_data', 'POST', true);
testEnforce(e, 'cathy', '/cathy_data', 'DELETE', false);

e = new Enforcer(m);
await e.initialize();
e = await Enforcer.newEnforcer(m);

testEnforce(e, 'alice', '/alice_data/resource1', 'GET', true);
testEnforce(e, 'alice', '/alice_data/resource1', 'POST', true);
Expand Down Expand Up @@ -88,8 +86,7 @@ test('TestKeyMatchModelInMemoryDeny', async () => {

const a = new FileAdapter('examples/keymatch_policy.csv');

const e = new Enforcer(m, a);
await e.initialize();
const e = await Enforcer.newEnforcer(m, a);

testEnforce(e, 'alice', '/alice_data/resource2', 'POST', true);
});

0 comments on commit 666fe23

Please sign in to comment.