mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-12-26 18:01:01 +08:00
started testing with roles
This commit is contained in:
parent
78da5dce42
commit
beca0b1e33
7 changed files with 1587 additions and 1461 deletions
61
api.js
61
api.js
|
@ -10,6 +10,8 @@ const MessageHandler = require('./lib/message-handler');
|
|||
const ImapNotifier = require('./lib/imap-notifier');
|
||||
const db = require('./lib/db');
|
||||
const certs = require('./lib/certs');
|
||||
const ObjectID = require('mongodb').ObjectID;
|
||||
const rootUser = new ObjectID('0'.repeat(24));
|
||||
|
||||
const usersRoutes = require('./lib/api/users');
|
||||
const addressesRoutes = require('./lib/api/addresses');
|
||||
|
@ -79,21 +81,64 @@ server.use(
|
|||
);
|
||||
|
||||
server.use((req, res, next) => {
|
||||
if (config.api.accessToken && ![req.query.accessToken, req.headers['x-access-token']].includes(config.api.accessToken)) {
|
||||
res.status(403);
|
||||
res.charSet('utf-8');
|
||||
return res.json({
|
||||
error: 'Invalid accessToken value'
|
||||
});
|
||||
}
|
||||
let accessToken = req.query.accessToken || req.headers['x-access-token'] || false;
|
||||
if (req.query.accessToken) {
|
||||
delete req.query.accessToken;
|
||||
}
|
||||
|
||||
let tokenRequired = false;
|
||||
|
||||
let fail = () => {
|
||||
res.status(403);
|
||||
res.charSet('utf-8');
|
||||
return res.json({
|
||||
error: 'Invalid accessToken value',
|
||||
code: 'InvalidToken'
|
||||
});
|
||||
};
|
||||
|
||||
req.validate = permission => {
|
||||
if (!permission.granted) {
|
||||
let err = new Error('Not enough privileges');
|
||||
err.responseCode = 403;
|
||||
err.code = 'MissingPrivileges';
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
// hard coded master token
|
||||
if (config.api.accessToken) {
|
||||
tokenRequired = true;
|
||||
if (config.api.accessToken === accessToken) {
|
||||
req.role = 'root';
|
||||
req.user = rootUser;
|
||||
return next();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: dynamically allocated tokens
|
||||
|
||||
if (tokenRequired) {
|
||||
// no valid token found
|
||||
return fail();
|
||||
}
|
||||
|
||||
// allow all
|
||||
req.role = 'root';
|
||||
req.user = rootUser;
|
||||
next();
|
||||
});
|
||||
|
||||
logger.token('user', req => (req.user && req.user.toString()) || '?'.repeat(24));
|
||||
logger.token('url', req => {
|
||||
if (/\baccessToken=/.test(req.url)) {
|
||||
return req.url.replace(/\baccessToken=[^&]+/g, 'accessToken=' + 'x'.repeat(6));
|
||||
}
|
||||
return req.url;
|
||||
});
|
||||
|
||||
server.use(
|
||||
logger(':method :url :status :time-spent :append', {
|
||||
logger(':remote-addr :user :method :url :status :time-spent :append', {
|
||||
stream: {
|
||||
write: message => {
|
||||
message = (message || '').toString();
|
||||
|
|
|
@ -19,6 +19,9 @@ enabled=false
|
|||
#cipher="aes192"
|
||||
#secret="a secret cat"
|
||||
|
||||
[roles]
|
||||
# @include "roles.json"
|
||||
|
||||
[tls]
|
||||
# If certificate path is not defined, use global or built-in self-signed certs
|
||||
#key="/path/to/server/key.pem"
|
||||
|
|
10
config/roles.json
Normal file
10
config/roles.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"root": {
|
||||
"addresses": {
|
||||
"create:any": ["*"],
|
||||
"read:any": ["*"],
|
||||
"update:any": ["*"],
|
||||
"delete:any": ["*"]
|
||||
}
|
||||
}
|
||||
}
|
2945
lib/api/addresses.js
2945
lib/api/addresses.js
File diff suppressed because it is too large
Load diff
13
lib/roles.js
Normal file
13
lib/roles.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
const config = require('wild-config');
|
||||
const AccessControl = require('accesscontrol');
|
||||
const ac = new AccessControl();
|
||||
|
||||
ac.setGrants(config.api.roles);
|
||||
|
||||
config.on('reload', () => {
|
||||
ac.setGrants(config.api.roles);
|
||||
});
|
||||
|
||||
module.exports.can = role => ac.can(role);
|
15
lib/tools.js
15
lib/tools.js
|
@ -488,9 +488,20 @@ module.exports = {
|
|||
try {
|
||||
await middleware(req, res, next);
|
||||
} catch (err) {
|
||||
res.json({
|
||||
let data = {
|
||||
error: err.message
|
||||
});
|
||||
};
|
||||
|
||||
if (err.responseCode) {
|
||||
res.status(err.responseCode);
|
||||
}
|
||||
|
||||
if (err.code) {
|
||||
data.code = err.code;
|
||||
}
|
||||
|
||||
res.charSet('utf-8');
|
||||
res.json(data);
|
||||
return next();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"request": "2.88.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"accesscontrol": "^2.2.1",
|
||||
"base32.js": "0.1.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bugsnag": "2.4.3",
|
||||
|
|
Loading…
Reference in a new issue