Skip to content

Commit 5220e2c

Browse files
authored
feat: general implementation (#2)
* chore: setup dev environment Signed-off-by: Zxilly <zhouxinyu1001@gmail.com> * feat: general implement Signed-off-by: Zxilly <zhouxinyu1001@gmail.com> * test: add unit tests Signed-off-by: Zxilly <zhouxinyu1001@gmail.com> * ci: add auto tests Signed-off-by: Zxilly <zhouxinyu1001@gmail.com> * build: ignore .idea Signed-off-by: Zxilly <zhouxinyu1001@gmail.com> * feat: add license for each file Signed-off-by: Zxilly <zhouxinyu1001@gmail.com>
1 parent 022ab35 commit 5220e2c

23 files changed

+5793
-62
lines changed

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lib
2+
examples

.eslintrc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"parser": "@typescript-eslint/parser",
3+
"extends": ["plugin:@typescript-eslint/recommended", "prettier", "plugin:prettier/recommended"],
4+
"rules": {
5+
"prettier/prettier": "error",
6+
"eqeqeq": "error",
7+
"@typescript-eslint/no-explicit-any": "off",
8+
"@typescript-eslint/no-unused-vars": "off",
9+
"@typescript-eslint/explicit-function-return-type": [
10+
"error",
11+
{
12+
"allowExpressions": true
13+
}
14+
],
15+
"@typescript-eslint/no-non-null-assertion": ["error"]
16+
},
17+
"env": {
18+
"jest": true,
19+
"node": true
20+
}
21+
}

.gitattributes

Whitespace-only changes.

.github/workflows/main.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: main
2+
on: [push, pull_request]
3+
jobs:
4+
test:
5+
runs-on: ${{ matrix.os }}
6+
strategy:
7+
fail-fast: false
8+
matrix:
9+
node-version: [^10, ^12, ^14]
10+
os: [ ubuntu-latest, macOS-latest, windows-latest]
11+
12+
steps:
13+
- uses: actions/checkout@v2
14+
- uses: actions/setup-node@v2
15+
with:
16+
node-version: ${{ matrix.node-version }}
17+
- run: yarn install --ignore-engines
18+
- run: yarn lint
19+
- run: yarn test
20+
- run: yarn coverage
21+
- name: Coveralls
22+
uses: coverallsapp/github-action@master
23+
with:
24+
github-token: ${{ secrets.GITHUB_TOKEN }}
25+
flag-name: run-${{ matrix.node-version }}-${{ matrix.os }}
26+
parallel: true

.gitignore

Lines changed: 21 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,64 @@
1-
# Logs
1+
.idea
2+
*.iml
3+
out
4+
gen
25
logs
36
*.log
47
npm-debug.log*
58
yarn-debug.log*
69
yarn-error.log*
710
lerna-debug.log*
8-
9-
# Diagnostic reports (https://nodejs.org/api/report.html)
1011
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11-
12-
# Runtime data
1312
pids
1413
*.pid
1514
*.seed
1615
*.pid.lock
17-
18-
# Directory for instrumented libs generated by jscoverage/JSCover
1916
lib-cov
20-
21-
# Coverage directory used by tools like istanbul
2217
coverage
2318
*.lcov
24-
25-
# nyc test coverage
2619
.nyc_output
27-
28-
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
2920
.grunt
30-
31-
# Bower dependency directory (https://bower.io/)
3221
bower_components
33-
34-
# node-waf configuration
3522
.lock-wscript
36-
37-
# Compiled binary addons (https://nodejs.org/api/addons.html)
3823
build/Release
39-
40-
# Dependency directories
4124
node_modules/
4225
jspm_packages/
43-
44-
# TypeScript v1 declaration files
45-
typings/
46-
47-
# TypeScript cache
26+
web_modules/
4827
*.tsbuildinfo
49-
50-
# Optional npm cache directory
5128
.npm
52-
53-
# Optional eslint cache
5429
.eslintcache
55-
56-
# Microbundle cache
5730
.rpt2_cache/
5831
.rts2_cache_cjs/
5932
.rts2_cache_es/
6033
.rts2_cache_umd/
61-
62-
# Optional REPL history
6334
.node_repl_history
64-
65-
# Output of 'npm pack'
6635
*.tgz
67-
68-
# Yarn Integrity file
6936
.yarn-integrity
70-
71-
# dotenv environment variables file
7237
.env
7338
.env.test
74-
75-
# parcel-bundler cache (https://parceljs.org/)
7639
.cache
77-
78-
# Next.js build output
40+
.parcel-cache
7941
.next
80-
81-
# Nuxt.js build / generate output
8242
.nuxt
8343
dist
84-
85-
# Gatsby files
8644
.cache/
87-
# Comment in the public line in if your project uses Gatsby and *not* Next.js
88-
# https://nextjs.org/blog/next-9-1#public-directory-support
89-
# public
90-
91-
# vuepress build output
9245
.vuepress/dist
93-
94-
# Serverless directories
9546
.serverless/
96-
97-
# FuseBox cache
9847
.fusebox/
99-
100-
# DynamoDB Local files
10148
.dynamodb/
102-
103-
# TernJS port file
10449
.tern-port
50+
.vscode-test
51+
.yarn/cache
52+
.yarn/unplugged
53+
.yarn/build-state.yml
54+
.yarn/install-state.gz
55+
.pnp.*
56+
cmake-build-*/
57+
*.iws
58+
out/
59+
.idea_modules/
60+
atlassian-ide-plugin.xml
61+
com_crashlytics_export_strings.xml
62+
crashlytics.properties
63+
crashlytics-build.properties
64+
fabric.properties

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"printWidth": 140,
5+
"endOfLine": "auto"
6+
}

.releaserc.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"debug": true,
3+
"plugins": [
4+
"@semantic-release/commit-analyzer",
5+
"@semantic-release/release-notes-generator",
6+
"@semantic-release/npm",
7+
[
8+
"@semantic-release/changelog",
9+
{
10+
"changelogFile": "CHANGELOG.md"
11+
}
12+
],
13+
[
14+
"@semantic-release/git",
15+
{
16+
"assets": ["package.json", "CHANGELOG.md"],
17+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
18+
}
19+
],
20+
"@semantic-release/github"
21+
]
22+
}

README.md

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,107 @@
1-
# graphql-authz
1+
# graphql-authz
2+
3+
graphql-authz is a Casbin authorization middleware for graphql-js
4+
5+
[![NPM version][npm-image]][npm-url]
6+
[![NPM download][download-image]][download-url]
7+
[![install size](https://packagephobia.now.sh/badge?p=graphql-authz)](https://packagephobia.now.sh/result?p=graphql-authz)
8+
[![GitHub Actions](https://github.com/node-casbin/graphql-authz/workflows/main/badge.svg)](https://github.com/node-casbin/graphql-authz/actions)
9+
[![Coverage Status](https://coveralls.io/repos/github/node-casbin/graphql-authz/badge.svg?branch=master)](https://coveralls.io/github/node-casbin/graphql-authz?branch=master)
10+
[![Release](https://img.shields.io/github/release/node-casbin/graphql-authz.svg)](https://github.com/node-casbin/graphql-authz/releases/latest)
11+
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/casbin/lobby)
12+
13+
[npm-image]: https://img.shields.io/npm/v/graphql-authz.svg?style=flat-square
14+
[npm-url]: https://npmjs.org/package/graphql-authz
15+
[download-image]: https://img.shields.io/npm/dm/graphql-authz.svg?style=flat-square
16+
[download-url]: https://npmjs.org/package/graphql-authz
17+
18+
## Installation
19+
20+
```shell
21+
npm install graphql-authz
22+
// or
23+
yarn add graphql-authz
24+
```
25+
26+
## Get Started
27+
28+
This package should use with `graphql` and `graphql-middleware`
29+
30+
To limit access to each endpoint, you can use casbin policy or graphql directive.
31+
32+
In the policy method, you can use casbin policy like
33+
```csv
34+
p,user,project.members,query
35+
p,roleb,project.members.tickets.id,query
36+
```
37+
to restricted access to each endpoint.
38+
39+
In the directive method, you can use directive `can` to do the same thing.
40+
41+
Here's a minimal example. You can find the full example in the `tests/server.test.ts`
42+
```typescript
43+
import { applyMiddleware } from 'graphql-middleware';
44+
import { newMiddleware, CanDirective } from 'graphql-authz';
45+
import { newEnforcer } from 'casbin';
46+
import { ApolloServer } from 'apollo-server';
47+
import { makeExecutableSchema } from '@graphql-tools/schema';
48+
import { CasbinContextEnforcerKey } from '../src';
49+
// After graphql-js 14.0.0, you should manually define directive in the SDL.
50+
const typeDefs = `
51+
directive @can(who: String!) on FIELD_DEFINITION
52+
53+
type User {
54+
id: ID! @can(who: "user")
55+
name: String @can(who: "someone")
56+
}
57+
`;
58+
59+
const resolvers = {
60+
// something
61+
};
62+
const schemaWithDirective = makeExecutableSchema({
63+
typeDefs,
64+
resolvers,
65+
schemaDirectives: {
66+
can: CanDirective,
67+
},
68+
});
69+
// If you want to use directive, this is necessary.
70+
// You can ignore this in the policy only method.
71+
72+
const enforcer = await newEnforcer('tests/casbin.conf', 'tests/policy.csv');
73+
// As for now, you should use model tests/casbin.conf to initialize enforcer.
74+
// For more info about enforcer, plz refer to https://github.com/casbin/node-casbin
75+
76+
const middleware = await newMiddleware({
77+
ctxMember: 'user', // middleware will get current user role from the graphql context[ctxMember]
78+
enforcer: enforcer, // Casbin Instance
79+
});
80+
81+
// Apply middlware to graphql schema
82+
const schemaWithDirectiveMiddleware = applyMiddleware(schemaWithDirective, middleware);
83+
84+
const server = new ApolloServer({
85+
schema: schemaWithDirectiveMiddleware,
86+
context: ({ req }) => {
87+
// Provide necessary info in the context.
88+
const token = req.headers.authorization || '';
89+
90+
// Try to retrieve a user with the token
91+
const user = getUser(token);
92+
93+
const a: any = {};
94+
a[CasbinContextEnforcerKey] = enforcer;
95+
a['user'] = user;
96+
return a;
97+
},
98+
});
99+
```
100+
101+
## Getting Help
102+
103+
- [Node-Casbin](https://github.com/casbin/node-casbin)
104+
105+
## License
106+
107+
This project is under Apache 2.0 License. See the [LICENSE](LICENSE) file for the full license text.

jest.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
testEnvironment: 'node',
3+
transform: {
4+
'^.+\\.(ts|tsx)$': 'ts-jest',
5+
},
6+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
7+
};

package.json

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"name": "graphql-authz",
3+
"version": "0.0.1",
4+
"description": "Integrated Casbin into GraphQL.js",
5+
"main": "lib/cjs/index.js",
6+
"typings": "lib/cjs/index.d.ts",
7+
"module": "lib/esm/index.js",
8+
"scripts": {
9+
"prepack": "run-s lint test build",
10+
"postpack": "run-s clean",
11+
"build": "run-s clean && run-p build:*",
12+
"build:cjs": "tsc -p tsconfig.cjs.json",
13+
"build:esm": "tsc -p tsconfig.esm.json",
14+
"test": "jest --forceExit",
15+
"lint": "eslint . --ext .js,.ts",
16+
"fmt": "eslint . --ext .js,.ts --fix",
17+
"clean": "rimraf lib",
18+
"coverage": "jest --forceExit --coverage"
19+
},
20+
"devDependencies": {
21+
"@graphql-tools/schema": "^7.1.5",
22+
"@types/jest": "^26.0.24",
23+
"@types/node": "^10.5.3",
24+
"@types/node-fetch": "^2.5.11",
25+
"@typescript-eslint/eslint-plugin": "^4.17.0",
26+
"@typescript-eslint/parser": "^4.17.0",
27+
"apollo-server": "^2.25.2",
28+
"casbin": "5.9.0",
29+
"eslint": "^7.30.0",
30+
"eslint-config-prettier": "^8.3.0",
31+
"eslint-plugin-prettier": "^3.4.0",
32+
"graphql": "^15.0.0",
33+
"graphql-middleware": "^6.0.0",
34+
"jest": "^27.0.6",
35+
"node-fetch": "^2.6.1",
36+
"npm-run-all": "^4.1.5",
37+
"prettier": "^2.2.1",
38+
"rimraf": "^3.0.2",
39+
"ts-jest": "^27.0.3",
40+
"tslint": "^5.11.0",
41+
"typescript": "^4.3.5"
42+
},
43+
"peerDependencies": {
44+
"graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0",
45+
"graphql-middleware": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^6.0.0"
46+
},
47+
"files": [
48+
"lib",
49+
"tests"
50+
],
51+
"homepage": "https://casbin.org",
52+
"repository": {
53+
"type": "git",
54+
"url": "https://github.com/node-casbin/graphql-authz.git"
55+
},
56+
"licenses": [
57+
{
58+
"type": "Apache-2.0",
59+
"url": "https://www.apache.org/licenses/LICENSE-2.0"
60+
}
61+
],
62+
"dependencies": {
63+
"casbin": "5.9.0",
64+
"@graphql-tools/utils": "^7.10.0"
65+
}
66+
}

0 commit comments

Comments
 (0)