Skip to content

Commit ef1dd90

Browse files
committed
docs(support): adds more examples and explanations in README
Also adds CONTRIBUTING.md which explains how to contribute to the project
1 parent 961a01b commit ef1dd90

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

CONTRIBUTING.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Contributing to CASL
2+
3+
I would love for you to contribute to CASL and help make it even better than it is
4+
today! As a contributor, here are the guidelines I would like you to follow:
5+
6+
- [Question or Problem?](#question)
7+
- [Issues and Bugs](#issue)
8+
- [Feature Requests](#feature)
9+
- [Submission Guidelines](#submit)
10+
- [Coding Rules](#rules)
11+
- [Commit Message Guidelines](#commit)
12+
13+
## <a name="question"></a> Got a Question or Problem?
14+
15+
Do not open issues for general support questions as I want to keep GitHub issues for bug reports and feature requests. You've got much better chances of getting your question answered on [gitter chat][gitter].
16+
17+
## <a name="issue"></a> Found a Bug?
18+
If you find a bug in the source code, you can help by [submitting an issue](#submit-issue) or even better, you can [submit a Pull Request](#submit-pr) with a fix.
19+
20+
## <a name="feature"></a> Missing a Feature?
21+
You can *request* a new feature by [submitting an issue](#submit-issue) to this GitHub Repository. If you would like to *implement* a new feature, please submit an issue with a proposal for your work first, to be sure that somebody else hasn't started to do the same.
22+
23+
## <a name="submit"></a> Submission Guidelines
24+
25+
### <a name="submit-issue"></a> Submitting an Issue
26+
27+
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
28+
29+
Please provide steps to reproduce for found bug (using http://plnkr.co or similar), this will help to understand and fix the issue faster.
30+
31+
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
32+
Before you submit your Pull Request (PR) consider the following guidelines:
33+
34+
* Search [GitHub](https://github.com/stalniy/casl/pulls) for an open or closed PR
35+
that relates to your submission. You don't want to duplicate effort.
36+
* Make your changes in a new git branch:
37+
38+
```sh
39+
git checkout -b my-fix-branch master
40+
```
41+
42+
* **include appropriate test cases**.
43+
* Follow defined [Coding Rules](#rules).
44+
* Run all test suites `npm test`
45+
* Commit your changes using a descriptive commit message that follows defined [commit message conventions](#commit). Adherence to these conventions is necessary because release notes are automatically generated from these messages.
46+
* Push your branch to GitHub:
47+
48+
```shell
49+
git push origin my-fix-branch
50+
```
51+
* In GitHub, send a pull request to `casl:master`.
52+
* If somebody from project contributors suggest changes then:
53+
* Make the required updates.
54+
* Re-run all test suites to ensure tests are still passing.
55+
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request). Basically you can use `git commit -a --amend` and `git push --force origin my-fix-branch` in order to keep single commit in the feature branch.
56+
57+
That's it! Thank you for your contribution!
58+
59+
## <a name="rules"></a> Coding Rules
60+
To ensure consistency throughout the source code, keep these rules in mind as you are working:
61+
62+
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
63+
* All public API methods **must be documented**.
64+
* Project follows [Airbnb's JavaScript Style Guide][js-style-guide] with [some exceptions](.eslintrc). All these will be checked by Travis ci when you submit your PR
65+
66+
## <a name="commit"></a> Commit Message Guidelines
67+
68+
The project have very precise rules over how git commit messages can be formatted. This leads to **more readable messages** that are easy to follow when looking through the **project history**. But also, git history is used to **generate the change log**.
69+
70+
The commit message format is borrowed from Angular projects and you can find [more details in this document][commit-message-format]
71+
72+
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
73+
[github]: https://github.com/stalniy/casl
74+
[gitter]: https://gitter.im/stalniy-casl/casl
75+
[js-style-guide]: https://github.com/airbnb/javascript

README.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
[![NPM version](https://badge.fury.io/js/casl.svg)](http://badge.fury.io/js/casl)
44
[![Build Status](https://travis-ci.org/stalniy/casl.svg?branch=master)](https://travis-ci.org/stalniy/casl)
55
[![codecov](https://codecov.io/gh/stalniy/casl/branch/master/graph/badge.svg)](https://codecov.io/gh/stalniy/casl)
6+
[![Join the chat at https://gitter.im/stalniy-casl/casl](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/stalniy-casl/casl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7+
68

79
CASL is an isomorphic authorization JavaScript library which restricts what resources a given user is allowed to access. All permissions are defined in a single location (the `Ability` class) and not duplicated across controllers, views, and database queries.
810

@@ -20,6 +22,128 @@ npm install casl --save
2022
* supports direct and inverted rules
2123
* provides [mongoose](https://github.com/Automattic/mongoose) plugin
2224
* can be easily integrated with any data storage
25+
* provides ES6 build, so you are able to shake out unused functionality
26+
27+
## Getting started
28+
29+
CASL allows you to use any data layer (e.g., `mongoose`, raw `mongodb` adapter, `sequalize`) and any HTTP framework (e.g., `koa`, `express`, `feathersjs`). It doesn't force you to choose even a database (however currently is the best integrated with MongoDB).
30+
31+
CASL concentrates all attention at what a user can actually do and allows to create abilities in DSL style. Lets see how
32+
33+
### 1. Define Abilities
34+
35+
Lets define `Ability` for a blog website where visitors:
36+
* can read everything.
37+
* can manage (i.e., create, update, delete, read) posts which were created by them
38+
* cannot delete post if it has at least 1 comment
39+
40+
```js
41+
import { AbilityBuilder } from 'casl'
42+
43+
const ability = AbilityBuilder.define((can, cannot) => {
44+
can('read', 'all')
45+
can('manage', 'Post', { author: loggedInUser.id })
46+
cannot('delete', 'Post', { 'comments.0': { $exists: true } })
47+
})
48+
```
49+
50+
Yes, you can use some operators from MongoDB query language to define conditions for your abilities.
51+
52+
### 2. Check Abilities
53+
54+
Later on you can check abilities using `can` and `cannot`.
55+
```js
56+
// true if ability allows to read at least one Post
57+
ability.can('read', 'Post')
58+
59+
// true if ability does not allow to read a post
60+
const post = new Post({ title: 'What is CASL?' })
61+
ability.cannot('read', post)
62+
```
63+
Also there is a conveninse method `throwUnlessCan` which throws `ForbiddenError` exception in case if action is not allowed on target object:
64+
```js
65+
import { ForbiddenError } from 'casl'
66+
67+
try {
68+
ability.throwUnlessCan('delete', post)
69+
} catch (error) {
70+
console.log(error instanceof Error) // true
71+
console.log(error instanceof ForbiddenError) // true
72+
}
73+
```
74+
75+
### 3. MongoDB integration
76+
77+
CASL provides easy integration with MongoDB database.
78+
```js
79+
const { toMongoQuery, AbilityBuilder } = require('casl')
80+
const { MongoClient } = require('mongodb')
81+
82+
const ability = AbilityBuilder.define(can => {
83+
can('read', 'Post', { author: 'me' })
84+
})
85+
86+
MongoClient.connect('mongodb://localhost:27017/blog', function(err, db) {
87+
const query = toMongoQuery(ability.rulesFor('read', 'Post')) // { $or: [{ author: 'me' }] }
88+
db.collection('posts').find(query) // find all Posts where author equals 'me'
89+
db.close();
90+
})
91+
```
92+
93+
And if you use [mongoose](https://github.com/Automattic/mongoose), you are lucky because CASL provides mongoose middleware which hides all boilerplate under convenient `accessibleBy` method.
94+
```js
95+
const { mongoosePlugin, AbilityBuilder } = require('casl')
96+
const mongoose = require('mongoose')
97+
98+
mongoose.plugin(mongoosePlugin)
99+
100+
const ability = AbilityBuilder.define(can => {
101+
can('read', 'Post', { author: 'me' })
102+
})
103+
104+
const Post = mongoose.model('Post', mongoose.Schema({
105+
title: String,
106+
author: String,
107+
content: String,
108+
createdAt: Date
109+
}))
110+
111+
// by default if asks for `read` rules
112+
// returns mongoose Query, so you can chain it with other conditions
113+
Post.accessibleBy(ability).where({ createdAt: { $gt: Date.now() - 24 * 3600 } })
114+
115+
// also you can call it on existing query to enforce visibility.
116+
// In this case it returns empty array because rules does not allow to read Posts of `someoneelse` author
117+
Post.find({ author: 'someoneelse' }).accessibleBy(ability).exec()
118+
```
119+
120+
### 4. UI integration
121+
122+
CASL is written in pure ES6 and has no dependencies on Node.js or other environments. That means you can use it on UI side. It may be useful if you need to show/hide some UI functionality based on what user can do in application.
123+
124+
```js
125+
import { Ability } from 'casl'
126+
127+
export class Session {
128+
constructor() {
129+
this.ability = new Ability()
130+
}
131+
132+
find() {
133+
return fetch('https://domain.com/session')
134+
.then(session => this.ability.update(session.rules))
135+
}
136+
137+
destroy() {
138+
return fetch('https://domain.com/session', { method: 'DELETE' })
139+
.then(() => this.ability.update([]))
140+
}
141+
}
142+
```
143+
144+
## Want to help?
145+
146+
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on guidelines for [contributing](CONTRIBUTING.md)
23147

24148
## License
25149

0 commit comments

Comments
 (0)