Skip to content

Commit

Permalink
add casbin role based access control
Browse files Browse the repository at this point in the history
  • Loading branch information
jakewmeyer committed May 31, 2020
1 parent 520ce6d commit f8daa8f
Show file tree
Hide file tree
Showing 22 changed files with 238 additions and 80 deletions.
22 changes: 7 additions & 15 deletions middleware/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,16 @@ const mongoose = require('mongoose');
const db = mongoose.connection.useDb('auth');

/**
* Auth + Authz middleware
*
* @returns {Function}
* Authentication middleware
*/
module.exports = (role) => async (ctx, next) => {
module.exports = async (ctx, next) => {
const key = ctx.request.headers['spacex-key'];
if (key) {
const data = await db.collection('users').findOne({ key });
if (data && data.key === key) {
if (role) {
if (data.roles && data.roles.includes(role)) {
await next();
return;
}
} else {
await next();
return;
}
const user = await db.collection('users').findOne({ key });
if (user && user.key === key) {
ctx.state.role = user.role;
await next();
return;
}
}
ctx.status = 401;
Expand Down
17 changes: 17 additions & 0 deletions middleware/authz/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

const { newEnforcer } = require('casbin');

/**
* Authorization middleware
*/
module.exports = async (ctx, next) => {
const { role } = ctx.state;
const { path, method } = ctx;
const enforcer = await newEnforcer(`${__dirname}/model.conf`, `${__dirname}/policy.csv`);
const allowed = await enforcer.enforce(role, path, method);
if (allowed) {
await next();
return;
}
ctx.status = 403;
};
14 changes: 14 additions & 0 deletions middleware/authz/model.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

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

[matchers]
m = g(r.sub, p.sub) && keyMatch2(r.obj, p.obj) && (r.act == p.act || p.act == "*")
104 changes: 104 additions & 0 deletions middleware/authz/policy.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
p, root, /*, *

p, create:capsule, /v4/capsules, POST
p, update:capsule, /v4/capsules/:id, PUT
p, delete:capsule, /v4/capsules/:id, DELETE

p, create:cores, /v4/cores, POST
p, update:cores, /v4/cores/:id, PUT
p, delete:cores, /v4/cores/:id, DELETE

p, create:crew, /v4/crew, POST
p, update:crew, /v4/crew/:id, PUT
p, delete:crew, /v4/crew/:id, DELETE

p, create:dragons, /v4/dragons, POST
p, update:dragons, /v4/dragons/:id, PUT
p, delete:dragons, /v4/dragons/:id, DELETE

p, create:landpads, /v4/landpads, POST
p, update:landpads, /v4/landpads/:id, PUT
p, delete:landpads, /v4/landpads/:id, DELETE

p, create:launches, /v4/launches, POST
p, update:launches, /v4/launches/:id, PUT
p, delete:launches, /v4/launches/:id, DELETE

p, create:launchpads, /v4/launchpads, POST
p, update:launchpads, /v4/launchpads/:id, PUT
p, delete:launchpads, /v4/launchpads/:id, DELETE

p, create:payloads, /v4/payloads, POST
p, update:payloads, /v4/payloads/:id, PUT
p, delete:payloads, /v4/payloads/:id, DELETE

p, create:rockets, /v4/rockets, POST
p, update:rockets, /v4/rockets/:id, PUT
p, delete:rockets, /v4/rockets/:id, DELETE

p, create:ships, /v4/ships, POST
p, update:ships, /v4/ships/:id, PUT
p, delete:ships, /v4/ships/:id, DELETE

p, update:company, /v4/company/:id, PUT

p, update:roadster, /v4/roadster/:id, PUT

p, get:user, /v4/users, GET
p, get-one:user, /v4/users/:id, GET
p, query:user, /v4/users/query, POST
p, create:user, /v4/users, POST
p, update:user, /v4/users/:id, PUT
p, delete:user, /v4/users/:id, DELETE

p, clear-cache, /v4/admin/cache, DELETE

g, superuser, root

g, create, create:capsule
g, update, update:capsule
g, delete, delete:capsule

g, create, create:cores
g, update, update:cores
g, delete, delete:cores

g, create, create:crew
g, update, update:crew
g, delete, delete:crew

g, create, create:dragons
g, update, update:dragons
g, delete, delete:dragons

g, create, create:landpads
g, update, update:landpads
g, delete, delete:landpads

g, create, create:launches
g, update, update:launches
g, delete, delete:launches

g, create, create:launchpads
g, update, update:launchpads
g, delete, delete:launchpads

g, create, create:payloads
g, update, update:payloads
g, delete, delete:payloads

g, create, create:rockets
g, update, update:rockets
g, delete, delete:rockets

g, create, create:ships
g, update, update:ships
g, delete, delete:ships

g, update, update:company

g, update, update:roadster

g, user, create
g, user, update
g, user, delete
1 change: 1 addition & 0 deletions middleware/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Export middleware
*/
module.exports.auth = require('./auth');
module.exports.authz = require('./authz');
module.exports.cache = require('./cache');
module.exports.responseTime = require('./response-time');
module.exports.logger = require('./logger');
45 changes: 37 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
},
"homepage": "https://github.com/r-spacex/SpaceX-API",
"dependencies": {
"casbin": "^5.0.3",
"cheerio": "^1.0.0-rc.3",
"cron": "^1.8.2",
"fuzzball": "^1.3.0",
Expand Down
4 changes: 2 additions & 2 deletions services/v4/admin/routes.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

const Router = require('koa-router');
const { auth, cache } = require('../../../middleware');
const { auth, authz, cache } = require('../../../middleware');

const router = new Router({
prefix: '/admin',
});

// Clear redis cache
router.delete('/cache', auth('basic'), async (ctx) => {
router.delete('/cache', auth, authz, async (ctx) => {
try {
await cache.redis.flushall();
ctx.status = 200;
Expand Down
8 changes: 4 additions & 4 deletions services/v4/capsules/routes.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

const Router = require('koa-router');
const Capsule = require('./model');
const { auth } = require('../../../middleware');
const { auth, authz } = require('../../../middleware');

const router = new Router({
prefix: '/capsules',
Expand Down Expand Up @@ -48,7 +48,7 @@ router.post('/query', async (ctx) => {
});

// Create capsule
router.post('/', auth('basic'), async (ctx) => {
router.post('/', auth, authz, async (ctx) => {
try {
const capsule = new Capsule(ctx.request.body);
await capsule.save();
Expand All @@ -59,7 +59,7 @@ router.post('/', auth('basic'), async (ctx) => {
});

// Update capsule
router.patch('/:id', auth('basic'), async (ctx) => {
router.patch('/:id', auth, authz, async (ctx) => {
try {
await Capsule.findByIdAndUpdate(ctx.params.id, ctx.request.body, { runValidators: true });
ctx.status = 200;
Expand All @@ -69,7 +69,7 @@ router.patch('/:id', auth('basic'), async (ctx) => {
});

// Delete capsule
router.delete('/:id', auth('basic'), async (ctx) => {
router.delete('/:id', auth, authz, async (ctx) => {
try {
await Capsule.findByIdAndDelete(ctx.params.id);
ctx.status = 200;
Expand Down
4 changes: 2 additions & 2 deletions services/v4/company/routes.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

const Router = require('koa-router');
const Company = require('./model');
const { auth } = require('../../../middleware');
const { auth, authz } = require('../../../middleware');

const router = new Router({
prefix: '/company',
Expand All @@ -20,7 +20,7 @@ router.get('/', async (ctx) => {
});

// Update company info
router.patch('/:id', auth('basic'), async (ctx) => {
router.patch('/:id', auth, authz, async (ctx) => {
try {
await Company.findByIdAndUpdate(ctx.params.id, ctx.request.body, { runValidators: true });
ctx.status = 200;
Expand Down
Loading

0 comments on commit f8daa8f

Please sign in to comment.