mirror of
https://github.com/zoriya/flood.git
synced 2026-06-02 19:11:14 +00:00
Add an option to completely disable users and authentication
Bug: Flood-UI/flood#240 Cherry-Pick: Flood-UI/flood#880 Signed-off-by: Jesse Chan <jc@linux.com>
This commit is contained in:
committed by
Jesse Chan
parent
52535e1eab
commit
5c4a22f0fd
@@ -15,6 +15,7 @@ const CONFIG = {
|
||||
ssl: process.env.FLOOD_ENABLE_SSL === 'true' || process.env.FLOOD_ENABLE_SSL === true,
|
||||
sslKey: '/data/flood_ssl.key',
|
||||
sslCert: '/data/flood_ssl.cert',
|
||||
disableUsersAndAuth: false,
|
||||
};
|
||||
|
||||
module.exports = CONFIG;
|
||||
|
||||
@@ -19,6 +19,23 @@ const CONFIG = {
|
||||
dbCleanInterval: 1000 * 60 * 60,
|
||||
// Where to store the local nedb database.
|
||||
dbPath: './server/db/',
|
||||
// If this is true, there will be no users and no attempt to
|
||||
// authenticate or password-protect any page. In that case,
|
||||
// instead of per-user config, the following configUser settings
|
||||
// will be used.
|
||||
disableUsersAndAuth: false,
|
||||
// Settings for the no-user configuration.
|
||||
configUser: {
|
||||
// How to connect to rTorrent. If this is true, it will connect
|
||||
// to the unix socket defined in socketPath.
|
||||
// Otherwise, it will connect via SCGI with the host and port.
|
||||
socket: true,
|
||||
// Path to the rTorrent unix socket.
|
||||
socketPath: '/path/to/rtorrent.sock',
|
||||
// SCGI host and port to connect to rTorrent.
|
||||
host: 'localhost',
|
||||
port: 5000,
|
||||
},
|
||||
// The host that Flood should listen for web connections on.
|
||||
// If you want to connect to Flood from hosts other that the one it is running
|
||||
// on, you should change this value.
|
||||
|
||||
@@ -89,6 +89,9 @@ const startWebServer = () => {
|
||||
const address = chalk.underline(`${useSSL ? 'https' : 'http'}://${host}:${port}`);
|
||||
|
||||
console.log(chalk.green(`Flood server starting on ${address}.\n`));
|
||||
if (config.disableUsersAndAuth) {
|
||||
console.log(chalk.yellow('Starting in insecure mode without authentication\n'));
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {startWebServer};
|
||||
|
||||
@@ -155,7 +155,23 @@ class Users {
|
||||
});
|
||||
}
|
||||
|
||||
getConfigUser() {
|
||||
const {socket} = config.configUser;
|
||||
return {
|
||||
_id: '_config',
|
||||
username: '_config',
|
||||
host: socket ? null : config.configUser.host,
|
||||
port: socket ? null : config.configUser.port,
|
||||
socketPath: socket ? config.configUser.socketPath : null,
|
||||
password: '',
|
||||
isAdmin: true,
|
||||
};
|
||||
}
|
||||
|
||||
listUsers(callback) {
|
||||
if (config.disableUsersAndAuth) {
|
||||
return callback([this.getConfigUser()]);
|
||||
}
|
||||
this.db.find({}, (err, users) => {
|
||||
if (err) {
|
||||
return callback(null, err);
|
||||
|
||||
+10
-1
@@ -12,8 +12,17 @@ const eventStream = require('../middleware/eventStream');
|
||||
const Filesystem = require('../models/Filesystem');
|
||||
const mediainfo = require('../util/mediainfo');
|
||||
const settings = require('../models/settings');
|
||||
const config = require('../../config');
|
||||
const Users = require('../models/Users');
|
||||
|
||||
router.use('/', passport.authenticate('jwt', {session: false}), appendUserServices);
|
||||
if (config.disableUsersAndAuth) {
|
||||
router.use('/', (req, res, next) => {
|
||||
req.user = Users.getConfigUser();
|
||||
appendUserServices(req, res, next);
|
||||
});
|
||||
} else {
|
||||
router.use('/', passport.authenticate('jwt', {session: false}), appendUserServices);
|
||||
}
|
||||
|
||||
router.use('/client', clientRoutes);
|
||||
|
||||
|
||||
+95
-80
@@ -42,6 +42,9 @@ const authValidation = joi.object().keys({
|
||||
});
|
||||
|
||||
router.use('/', (req, res, next) => {
|
||||
if (config.disableUsersAndAuth) {
|
||||
req.user = Users.getConfigUser();
|
||||
}
|
||||
const validation = joi.validate(req.body, authValidation);
|
||||
|
||||
if (!validation.error) {
|
||||
@@ -54,9 +57,14 @@ router.use('/', (req, res, next) => {
|
||||
}
|
||||
});
|
||||
|
||||
router.use('/users', passport.authenticate('jwt', {session: false}), requireAdmin);
|
||||
if (!config.disableUsersAndAuth) {
|
||||
router.use('/users', passport.authenticate('jwt', {session: false}), requireAdmin);
|
||||
}
|
||||
|
||||
router.post('/authenticate', (req, res) => {
|
||||
if (config.disableUsersAndAuth) {
|
||||
return setAuthToken(res, req.user._id, true);
|
||||
}
|
||||
const credentials = {
|
||||
password: req.body.password,
|
||||
username: req.body.username,
|
||||
@@ -74,44 +82,49 @@ router.post('/authenticate', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// Allow unauthenticated registration if no users are currently registered.
|
||||
router.use('/register', (req, res, next) => {
|
||||
Users.initialUserGate({
|
||||
handleInitialUser: () => {
|
||||
next();
|
||||
},
|
||||
handleSubsequentUser: () => {
|
||||
passport.authenticate('jwt', {session: false}, (passportReq, passportRes) => {
|
||||
passportRes.json({username: req.username});
|
||||
});
|
||||
},
|
||||
if (!config.disableUsersAndAuth) {
|
||||
// Allow unauthenticated registration if no users are currently registered.
|
||||
router.use('/register', (req, res, next) => {
|
||||
Users.initialUserGate({
|
||||
handleInitialUser: () => {
|
||||
next();
|
||||
},
|
||||
handleSubsequentUser: () => {
|
||||
passport.authenticate('jwt', {session: false}, (passportReq, passportRes) => {
|
||||
passportRes.json({username: req.username});
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.post('/register', (req, res) => {
|
||||
// Attempt to save the user
|
||||
Users.createUser(
|
||||
{
|
||||
username: req.body.username,
|
||||
password: req.body.password,
|
||||
host: req.body.host,
|
||||
port: req.body.port,
|
||||
socketPath: req.body.socketPath,
|
||||
isAdmin: true,
|
||||
},
|
||||
(createUserResponse, createUserError) => {
|
||||
if (createUserError) {
|
||||
ajaxUtil.getResponseFn(res)(createUserResponse, createUserError);
|
||||
return;
|
||||
}
|
||||
router.post('/register', (req, res) => {
|
||||
// Attempt to save the user
|
||||
Users.createUser(
|
||||
{
|
||||
username: req.body.username,
|
||||
password: req.body.password,
|
||||
host: req.body.host,
|
||||
port: req.body.port,
|
||||
socketPath: req.body.socketPath,
|
||||
isAdmin: true,
|
||||
},
|
||||
(createUserResponse, createUserError) => {
|
||||
if (createUserError) {
|
||||
ajaxUtil.getResponseFn(res)(createUserResponse, createUserError);
|
||||
return;
|
||||
}
|
||||
|
||||
setAuthToken(res, req.body.username, true);
|
||||
},
|
||||
);
|
||||
});
|
||||
setAuthToken(res, req.body.username, true);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Allow unauthenticated verification if no users are currently registered.
|
||||
router.use('/verify', (req, res, next) => {
|
||||
if (config.disableUsersAndAuth) {
|
||||
return next();
|
||||
}
|
||||
Users.initialUserGate({
|
||||
handleInitialUser: () => {
|
||||
req.initialUser = true;
|
||||
@@ -132,63 +145,65 @@ router.get('/verify', (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// All subsequent routes are protected.
|
||||
router.use('/', passport.authenticate('jwt', {session: false}));
|
||||
if (!config.disableUsersAndAuth) {
|
||||
// All subsequent routes are protected.
|
||||
router.use('/', passport.authenticate('jwt', {session: false}));
|
||||
|
||||
router.get('/logout', (req, res) => {
|
||||
res.clearCookie('jwt').send();
|
||||
});
|
||||
router.get('/logout', (req, res) => {
|
||||
res.clearCookie('jwt').send();
|
||||
});
|
||||
|
||||
router.use('/users', (req, res, next) => {
|
||||
if (req.user && req.user.isAdmin) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
router.use('/users', (req, res, next) => {
|
||||
if (req.user && req.user.isAdmin) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(401).send('Not authorized');
|
||||
});
|
||||
res.status(401).send('Not authorized');
|
||||
});
|
||||
|
||||
router.get('/users', (req, res) => {
|
||||
Users.listUsers(ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
router.get('/users', (req, res) => {
|
||||
Users.listUsers(ajaxUtil.getResponseFn(res));
|
||||
});
|
||||
|
||||
router.delete('/users/:username', (req, res) => {
|
||||
Users.removeUser(req.params.username, ajaxUtil.getResponseFn(res));
|
||||
services.destroyUserServices(req.user);
|
||||
});
|
||||
router.delete('/users/:username', (req, res) => {
|
||||
Users.removeUser(req.params.username, ajaxUtil.getResponseFn(res));
|
||||
services.destroyUserServices(req.user);
|
||||
});
|
||||
|
||||
router.patch('/users/:username', (req, res) => {
|
||||
const {username} = req.params;
|
||||
const userPatch = req.body;
|
||||
router.patch('/users/:username', (req, res) => {
|
||||
const {username} = req.params;
|
||||
const userPatch = req.body;
|
||||
|
||||
if (!userPatch.socketPath) {
|
||||
userPatch.socketPath = null;
|
||||
} else {
|
||||
userPatch.host = null;
|
||||
userPatch.port = null;
|
||||
}
|
||||
if (!userPatch.socketPath) {
|
||||
userPatch.socketPath = null;
|
||||
} else {
|
||||
userPatch.host = null;
|
||||
userPatch.port = null;
|
||||
}
|
||||
|
||||
Users.updateUser(username, userPatch, () => {
|
||||
Users.lookupUser({username}, (err, user) => {
|
||||
if (err) return req.status(500).json({error: err});
|
||||
services.updateUserServices(user);
|
||||
res.send();
|
||||
Users.updateUser(username, userPatch, () => {
|
||||
Users.lookupUser({username}, (err, user) => {
|
||||
if (err) return req.status(500).json({error: err});
|
||||
services.updateUserServices(user);
|
||||
res.send();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
router.put('/users', (req, res) => {
|
||||
Users.createUser(
|
||||
{
|
||||
username: req.body.username,
|
||||
password: req.body.password,
|
||||
host: req.body.host,
|
||||
port: req.body.port,
|
||||
socketPath: req.body.socketPath,
|
||||
isAdmin: req.body.isAdmin,
|
||||
},
|
||||
ajaxUtil.getResponseFn(res),
|
||||
);
|
||||
});
|
||||
router.put('/users', (req, res) => {
|
||||
Users.createUser(
|
||||
{
|
||||
username: req.body.username,
|
||||
password: req.body.password,
|
||||
host: req.body.host,
|
||||
port: req.body.port,
|
||||
socketPath: req.body.socketPath,
|
||||
isAdmin: req.body.isAdmin,
|
||||
},
|
||||
ajaxUtil.getResponseFn(res),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user