Add permission level checks

pull/1/head
Florian Hartwich 2017-06-08 13:14:53 +02:00
parent a215d41ec3
commit 9b8bcd0722
10 changed files with 57 additions and 27 deletions

View File

@ -2,6 +2,7 @@
const jwt = require('jsonwebtoken');
const config = require('../config/config');
const AppUser = require('../models/app-user');
const apiAuthentication = (req, res, next) => {
@ -18,7 +19,16 @@ const apiAuthentication = (req, res, next) => {
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
AppUser.findById(decoded.sub, (err, item) => {
if (err) {
return res.status(403).send({
success: false,
message: 'token is not associated to any actual user'
});
}
req.user = item;
next();
});
}
});

View File

@ -0,0 +1,20 @@
"use strict";
let check = (requiredPermission, actualPermission, res, next) => {
if (actualPermission >= requiredPermission) {
return next();
}
return res.status(403).send({
success: false,
message: 'permission denied'
});
};
module.exports = {
checkSql: (req, res, next) => { check(1, req.user.permission, res, next) },
checkHl: (req, res, next) => { check(2, req.user.permission, res, next) },
checkMT: (req, res, next) => { check(3, req.user.permission, res, next) },
checkAdmin: (req, res, next) => { check(4, req.user.permission, res, next) }
};

View File

@ -1,4 +1,4 @@
"use strict"
"use strict";
const sortCollectionBy = (collection, key) => {
collection.sort((a, b) => {

View File

@ -18,7 +18,7 @@ const AppUserSchema = new Schema({
get: v => Math.round(v),
set: v => Math.round(v),
min: 0,
max: 3,
max: 4,
default: 0
}
}, {

View File

@ -12,6 +12,7 @@ const logger = require('debug')('cc:decorations');
const codes = require('./http-codes');
const apiAuthenticationMiddleware = require('../middleware/auth-middleware');
const checkHl = require('../middleware/permission-check').checkHl;
const routerHandling = require('../middleware/router-handling');
// Mongoose Model using mongoDB
@ -46,7 +47,7 @@ decoration.route('/')
});
})
.post(apiAuthenticationMiddleware, upload.single('image'), (req, res, next) => {
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
const decoration = new DecorationModel(req.body);
// timestamp and default are set automatically by Mongoose Schema Validation
decoration.save((err) => {
@ -86,7 +87,7 @@ decoration.route('/:id')
});
})
.patch(apiAuthenticationMiddleware, upload.single('image'), (req, res, next) => {
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
@ -125,7 +126,7 @@ decoration.route('/:id')
})
})
.delete(apiAuthenticationMiddleware, (req, res, next) => {
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
DecorationModel.findByIdAndRemove(req.params.id, (err, item) => {
if (err) {
err.status = codes.wrongrequest;

View File

@ -12,6 +12,7 @@ const logger = require('debug')('cc:ranks');
const codes = require('./http-codes');
const apiAuthenticationMiddleware = require('../middleware/auth-middleware');
const checkHl = require('../middleware/permission-check').checkHl;
const routerHandling = require('../middleware/router-handling');
// Mongoose Model using mongoDB
@ -49,7 +50,7 @@ ranks.route('/')
});
})
.post(apiAuthenticationMiddleware, upload.single('image'), (req, res, next) => {
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
const rank = new RankModel(req.body);
// timestamp and default are set automatically by Mongoose Schema Validation
rank.save((err) => {
@ -89,7 +90,7 @@ ranks.route('/:id')
});
})
.patch(apiAuthenticationMiddleware, upload.single('image'), (req, res, next) => {
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
@ -130,7 +131,7 @@ ranks.route('/:id')
})
})
.delete(apiAuthenticationMiddleware, (req, res, next) => {
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
RankModel.findByIdAndRemove(req.params.id, (err, item) => {
if (err) {
err.status = codes.wrongrequest;

View File

@ -12,6 +12,7 @@ const logger = require('debug')('cc:squads');
const codes = require('./http-codes');
const apiAuthenticationMiddleware = require('../middleware/auth-middleware');
const checkHl = require('../middleware/permission-check').checkHl;
const routerHandling = require('../middleware/router-handling');
// Mongoose Model using mongoDB
@ -44,7 +45,7 @@ squads.route('/')
});
})
.post(apiAuthenticationMiddleware, upload.single('image'), (req, res, next) => {
.post(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
const squad = new SquadModel(req.body);
// timestamp and default are set automatically by Mongoose Schema Validation
if (req.file) {
@ -89,7 +90,7 @@ squads.route('/:id')
});
})
.patch(apiAuthenticationMiddleware, upload.single('image'), (req, res, next) => {
.patch(apiAuthenticationMiddleware, checkHl, upload.single('image'), (req, res, next) => {
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
@ -129,7 +130,7 @@ squads.route('/:id')
})
})
.delete(apiAuthenticationMiddleware, (req, res, next) => {
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
SquadModel.findByIdAndRemove(req.params.id, (err, item) => {
if (err) {
err.status = codes.wrongrequest;

View File

@ -9,6 +9,7 @@ const logger = require('debug')('me2u5:users');
const codes = require('./http-codes');
const apiAuthenticationMiddleware = require('../middleware/auth-middleware');
const checkHl = require('../middleware/permission-check').checkHl;
const sortCollectionBy = require('../middleware/util').sortCollection;
const routerHandling = require('../middleware/router-handling');
@ -84,7 +85,7 @@ users.route('/')
}
})
.post(apiAuthenticationMiddleware, (req, res, next) => {
.post(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
const user = new UserModel(req.body);
// timestamp and default are set automatically by Mongoose Schema Validation
user.save((err) => {
@ -129,7 +130,7 @@ users.route('/:id')
});
})
.patch(apiAuthenticationMiddleware, (req, res, next) => {
.patch(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
@ -176,7 +177,7 @@ users.route('/:id')
})
})
.put(apiAuthenticationMiddleware, (req, res, next) => {
.put(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
// first check that the given element id is the same as the URL id
if (!req.body || req.body._id !== req.params.id) {
// the URL does not fit the given element
@ -231,7 +232,7 @@ users.route('/:id')
})
})
.delete(apiAuthenticationMiddleware, (req, res, next) => {
.delete(apiAuthenticationMiddleware, checkHl, (req, res, next) => {
UserModel.findByIdAndRemove(req.params.id, (err, item) => {
if (err) {
err.status = codes.wrongrequest;

View File

@ -15,6 +15,8 @@ const urls = require('./config/api-url');
const restAPIchecks = require('./middleware/request-checks.js');
const errorResponseWare = require('./middleware/error-response');
const apiAuthenticationMiddleware = require('./middleware/auth-middleware');
const checkHl = require('./middleware/permission-check').checkHl;
const checkAdmin = require('./middleware/permission-check').checkAdmin;
const signatureCronJob = require('./cron-job/update-signatures');
// router modules
@ -54,7 +56,7 @@ app.use(restAPIchecks);
// Routes ******************************************************
app.use(urls.signatures, signatureRouter);
// initialize logging here to exclude /signature requests
// initialize logging at this point to exclude /signature requests
if (process.env.NODE_ENV === config.dev.env) {
// development logging
app.use(requestLogger('dev'));
@ -69,8 +71,8 @@ app.use(urls.users, userRouter);
app.use(urls.squads, squadRouter);
app.use(urls.ranks, rankRouter);
app.use(urls.decorations, decorationRouter);
app.use(urls.awards, apiAuthenticationMiddleware, awardingRouter);
app.use(urls.command, apiAuthenticationMiddleware, commandRouter);
app.use(urls.awards, apiAuthenticationMiddleware, checkHl, awardingRouter);
app.use(urls.command, apiAuthenticationMiddleware, checkAdmin, commandRouter);
// send index.html on all different paths
app.use(function (req, res) {
@ -105,13 +107,6 @@ if (process.env.NODE_ENV !== config.test.env) {
});
} else {
mongoose.connect(config.database.uri + config.test.db);
for (let collection in mongoose.connection.collections) {
mongoose.connection.collections[collection].drop(function (err) {
if (err) {
console.log('Error while test-Db clean up: ' + err);
}
});
}
app.listen(config.test.port);
console.log('Listening on port ' + config.test.port);
}

View File

@ -51,7 +51,8 @@ describe('Users', () => {
before(function (done) {
let appUser = {
username: 'testUsr',
password: '$2a$10$i9cBC06uGJnnrqQCh8COkuZLMChLQqw5j4K0yfDQn1udTDAompHka'
password: '$2a$10$i9cBC06uGJnnrqQCh8COkuZLMChLQqw5j4K0yfDQn1udTDAompHka',
permission: 2
};
let appUserEncoded = {
username: appUser.username,