Skip to content
Snippets Groups Projects
Commit 88473f0d authored by iaibrys's avatar iaibrys
Browse files

Add fine-grained authentication

parent d698d8f4
No related branches found
No related tags found
No related merge requests found
Pipeline #361 passed
**/node_modules
.idea
......@@ -5,3 +5,6 @@
[submodule "deps/RichFilemanager-NODE"]
path = deps/RichFilemanager-NODE
url = https://github.com/dtu-compute/RichFilemanager-NODE
[submodule "deps/RichFilemanager-NODE-auth"]
path = deps/RichFilemanager-NODE-auth
url = https://github.com/dtu-compute/RichFilemanager-NODE-auth
# filemanager
## Local Testing
```
DTU_FILEMANAGER_ROOT=${DTU_ENOTE_VOL}/content npm run serve
```
Go to `http://localhost:5000/index.html`. This uses the redis user store so it'll need to have that up and running too.
Subproject commit ac54e581fe484629514a6903006293b5a8e7161c
Subproject commit ac7a1eb9ed1334360d96bf399eb5acf1275f078a
Subproject commit 78a59e3bb5c144e180073d40979849545cc4d5ac
......@@ -8,6 +8,9 @@ const session = require('express-session');
const redis = require('redis');
let RedisStore = require('connect-redis')(session);
const $redis = redis.createClient({host: 'redis', port: '6379'});
const multer = require('multer');
const upload = multer({dest: 'public/'});
const authedFilemanager = require('richfilemanager-node-auth');
const filemanager = require(path.resolve(
__dirname,
......@@ -15,41 +18,60 @@ const filemanager = require(path.resolve(
'rich-filemanager-node'
));
const PUBLIC_ROOT = process.env.PUBLIC_ROOT || path.join(__dirname, 'public');
const config = path.join(PUBLIC_ROOT, 'config', 'filemanager.config.json');
const LOCAL_ROOT = process.env.DTU_FILEMANAGER_ROOT || './no-access';
const rfmNodeConfig = path.join(PUBLIC_ROOT, 'config', 'filemanager.config.json');
const port = process.env.PORT || 5000;
const serverBaseURL = process.env.ENOTE_DOMAIN_SUFFIX ?
`https://filemanager${process.env.ENOTE_DOMAIN_SUFFIX}` :
'http://localhost:5000';
`http://localhost:${port}`;
let app = express();
const authFilemanager = (req, res, next) => {
function authPath(targetPath, req, isFile, access) {
const user = req.user;
const segs = (targetPath || path.sep).split(path.sep).filter(x => x && x !== '');
console.dir(segs);
const course = segs[0];
const targetPath = req.query.path;
console.log(`authPath ${targetPath} ${isFile || false} ${access}`);
console.log("course: %o", course);
if (!!req.user) {
console.log(`SUCCESS Authorizing ${req.originalUrl} ${req.url} ${req.user} ${targetPath} [already logged in]`);
const course = (targetPath || '/').split(path.sep)[0];
console.log(course);
const roleFilter = (role) => ((!course || (role.course_id === course)) && (role.acl === 'administrator'));
const roles = (req.user.role || []).filter(roleFilter);
const roleFilter = (role) => ((!course || role.course_id === course) && (role.acl === 'administrator'));
const roles = (user.role || []).filter(roleFilter);
console.dir(roles);
if (!roles.length) {
console.error(`user ${req.user.profile.user} not authorized for path ${targetPath}`);
return roles.length > 0;
}
function authError(req, res, paths) {
if (typeof paths === 'String') { paths = [paths] }
console.error(`user ${req.user.profile.user} not authorized for path(s) %o`, paths);
console.error(JSON.stringify(req.user, null, 2));
res.status(403);
return res.json({error: 'unauthorized'});
}
const authFilemanager = (req, res, next) => {
const targetPath = req.query.path;
if (!!req.user) {
console.log(`SUCCESS Authorizing ${req.originalUrl} ${req.url} %o ${targetPath} [already logged in]`, req.user);
if (targetPath && !authPath(targetPath, req)) {
return authError(req, res, targetPath);
}
return next();
}
console.log(`Authorizing ${req.originalUrl} ${req.url} ${req.user} ${path}`);
return passport.authenticate('cas', function (err, user, info) {
console.log(`Auth callback for ${req.originalUrl} ${req.url}`);
console.dir(err);
......@@ -76,7 +98,7 @@ const authFilemanager = (req, res, next) => {
req.session.messages = '';
console.log('redirecting');
console.dir(err);
console.log('err: %o', err);
return res.redirect('/');
});
......@@ -86,8 +108,7 @@ const authFilemanager = (req, res, next) => {
const authRequest = (req, res, next) => {
if (!!req.user) {
next();
return;
return next();
}
console.log(`Authorizing ${req.originalUrl} ${req.url} ${req.user}`);
return passport.authenticate('cas', function (err, user, info) {
......@@ -167,15 +188,18 @@ app.use(session({
app.use(passport.initialize(null));
app.use(passport.session());
app.use('/', [authRequest, express.static(PUBLIC_ROOT)]);
app.use('/filemanager', [authFilemanager, filemanager(process.env.DTU_FILEMANAGER_ROOT || './no-access', config)]);
const richFileManagerNodeArgs = {
appRoot: LOCAL_ROOT,
configFile: rfmNodeConfig
}
const afmConfig = { authPath, authError, filemanager, richFileManagerNodeArgs };
app.use('/filemanager', [authFilemanager, authedFilemanager(afmConfig)]);
app.use('/unauthorized', (req, res, next) => {
req.logOut();
res.sendFile('unauthorized.html', {root: PUBLIC_ROOT });
});
//Listen for requests
const port = process.env.PORT || 5000;
app.listen(port, function () {
console.log(`App listening on port ${port}; root=${PUBLIC_ROOT}; external=${serverBaseURL}`);
console.log(`App listening on port ${port}; root=${PUBLIC_ROOT}; local_root=${LOCAL_ROOT} external=${serverBaseURL}`);
});
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment