Skip to content
This repository was archived by the owner on Oct 5, 2020. It is now read-only.

Commit 0ab17c8

Browse files
committed
Fixed #288: by-pass auth entirely in node with few lines
1 parent fe07777 commit 0ab17c8

File tree

5 files changed

+92
-28
lines changed

5 files changed

+92
-28
lines changed

app/templates/node-server/node-app.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,17 @@ app.use(expressSession({
1717
resave: true
1818
}));
1919

20+
//
21+
// Uncomment the following to by-pass authentication entirely by enforcing defaultUser on the session.
22+
//
23+
// Note: consider blocking update calls in the proxy when enabling this.
24+
//
25+
// app.use(function (req, res, next) {
26+
// var options = require('./utils/options')();
27+
// req.session.user = { name: options.defaultUser, password: options.defaultPass, profile: { fullname: 'Guest' } };
28+
// next();
29+
// });
30+
2031
app.use(logger('dev'));
2132

2233
app.use('/v1', require('./proxy'));

app/templates/node-server/proxy.js

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@
44

55
var router = require('express').Router();
66
var http = require('http');
7-
var config = require('../gulp.config')();
8-
9-
var options = {
10-
mlHost: process.env.ML_HOST || config.marklogic.host,
11-
mlHttpPort: process.env.ML_PORT || config.marklogic.httpPort,
12-
defaultUser: process.env.ML_APP_USER || config.marklogic.user,
13-
defaultPass: process.env.ML_APP_PASS || config.marklogic.password
14-
};
7+
var options = require('./utils/options')();
158

169
// ==================================
1710
// MarkLogic REST API endpoints
1811
// ==================================
12+
13+
//
14+
// To not require authentication for a specific route, simply use the route below.
15+
// Copy and change according to your needs.
16+
//
17+
//router.get('/my/route', function(req, res) {
18+
// noCache(res);
19+
// proxy(req, res);
20+
//});
21+
1922
// For any other GET request, proxy it on to MarkLogic.
2023
router.get('*', function(req, res) {
2124
noCache(res);
@@ -24,10 +27,9 @@ router.get('*', function(req, res) {
2427
} else {
2528
proxy(req, res);
2629
}
27-
// To not require authentication, simply use the proxy below:
28-
//proxy(req, res);
2930
});
3031

32+
// PUT requires special treatment, as a user could be trying to PUT a profile update..
3133
router.put('*', function(req, res) {
3234
noCache(res);
3335
// For PUT requests, require authentication
@@ -36,11 +38,12 @@ router.put('*', function(req, res) {
3638
} else if (req.path === '/v1/documents' &&
3739
req.query.uri.match('/api/users/') &&
3840
req.query.uri.match(new RegExp('/api/users/[^(' + req.session.user.name + ')]+.json'))) {
39-
// The user is try to PUT to a profile document other than his/her own. Not allowed.
41+
// The user is trying to PUT to a profile document other than his/her own. Not allowed.
4042
res.status(403).send('Forbidden');
4143
} else {
4244
if (req.path === '/v1/documents' && req.query.uri.match('/users/')) {
43-
// TODO: The user is updating the profile. Update the session info.
45+
var json = req.body.user ? req.body : JSON.parse(req.body);
46+
req.session.user.profile = json.user;
4447
}
4548
proxy(req, res);
4649
}
@@ -122,9 +125,9 @@ function proxy(req, res) {
122125
}
123126

124127
function noCache(response){
125-
response.append('Cache-Control', 'no-cache, must-revalidate');//HTTP 1.1 - must-revalidate
126-
response.append('Pragma', 'no-cache');//HTTP 1.0
127-
response.append('Expires', 'Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
128+
response.append('Cache-Control', 'no-cache, must-revalidate'); // HTTP 1.1 - must-revalidate
129+
response.append('Pragma', 'no-cache'); // HTTP 1.0
130+
response.append('Expires', 'Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
128131
}
129132

130133
module.exports = router;

app/templates/node-server/routes.js

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,7 @@ var router = require('express').Router();
66
var bodyParser = require('body-parser');
77
var four0four = require('./utils/404')();
88
var http = require('http');
9-
var config = require('../gulp.config')();
10-
11-
var options = {
12-
appPort: process.env.APP_PORT || config.defaultPort,
13-
mlHost: process.env.ML_HOST || config.marklogic.host,
14-
mlHttpPort: process.env.ML_PORT || config.marklogic.httpPort,
15-
defaultUser: process.env.ML_APP_USER || config.marklogic.user,
16-
defaultPass: process.env.ML_APP_PASS || config.marklogic.password
17-
};
9+
var options = require('./utils/options')();
1810

1911
// [GJo] (#31) Moved bodyParsing inside routing, otherwise it might try to parse uploaded binaries as json..
2012
router.use(bodyParser.urlencoded({extended: true}));
@@ -52,7 +44,7 @@ router.get('/user/status', function(req, res) {
5244
res.status(200).send({
5345
authenticated: true,
5446
username: req.session.user.name,
55-
profile: {}
47+
profile: req.session.user.profile || {}
5648
});
5749
} else {
5850
res.send({authenticated: false});
@@ -97,7 +89,8 @@ router.post('/user/login', function(req, res) {
9789
};
9890
res.status(200).send({
9991
authenticated: true,
100-
username: username
92+
username: username,
93+
profile: {}
10194
});
10295
} else {
10396
console.log('code: ' + response.statusCode);
@@ -115,6 +108,7 @@ router.post('/user/login', function(req, res) {
115108
username: username,
116109
profile: json.user
117110
});
111+
req.session.user.profile = json.user;
118112
} else {
119113
console.log('did not find chunk.user');
120114
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* jshint node:true */
2+
3+
'use strict';
4+
5+
var config = require('../../gulp.config')();
6+
7+
module.exports = function(){
8+
9+
var environment = process.env.NODE_ENV;
10+
var envJson = getEnvOptions(environment === 'build' ? 'prod' : 'local');
11+
12+
var options = {
13+
appPort: process.env.APP_PORT || envJson['node-port'] || config.defaultPort,
14+
mlHost: process.env.ML_HOST || envJson['ml-host'] || config.marklogic.host,
15+
mlHttpPort: process.env.ML_PORT || envJson['ml-http-port'] || config.marklogic.httpPort,
16+
defaultUser: process.env.ML_APP_USER || envJson['ml-app-user'] || config.marklogic.user,
17+
defaultPass: process.env.ML_APP_PASS || envJson['ml-app-pass'] || config.marklogic.password
18+
};
19+
20+
return options;
21+
22+
function getEnvOptions(env) {
23+
var envJson;
24+
var envFile = '../../' + env + '.json';
25+
26+
try {
27+
envJson = require(envFile);
28+
}
29+
catch (e) {
30+
envJson = {};
31+
console.log('Couldn\'t find ' + envFile + '; you can create this file to override properties - ' +
32+
'`gulp init-local` creates local.json which can be modified for other environments as well');
33+
}
34+
35+
return envJson;
36+
}
37+
38+
};

slushfile.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ function configRoxy() {
182182
// set the authentication-method property to digestbasic
183183
properties = properties.replace(/^authentication\-method=digest/m, 'authentication-method=digestbasic');
184184

185+
// capture appuser-password generated by Roxy for later use
186+
var passwordMatch = /^appuser\-password=(.*)$/m;
187+
var matches = passwordMatch.exec(properties);
188+
settings.appuserPassword = matches[1];
189+
185190
fs.writeFileSync('deploy/build.properties', properties);
186191
} catch (e) {
187192
console.log('failed to update properties: ' + e.message);
@@ -254,6 +259,18 @@ function configRoxy() {
254259
' <range-value-positions>false</range-value-positions>\n' +
255260
' </geospatial-element-pair-index>\n');
256261

262+
// fix default app-role privileges to match rest-style applications
263+
foo = foo.replace(/<privileges>[^]*?<\/privileges>/,
264+
'<privileges>\n' +
265+
' <privilege>\n' +
266+
' <privilege-name>rest-reader</privilege-name>\n' +
267+
' </privilege>\n' +
268+
' <!-- remove the rest-writer privilege if read-only access is required -->\n' +
269+
' <privilege>\n' +
270+
' <privilege-name>rest-writer</privilege-name>\n' +
271+
' </privilege>\n' +
272+
' </privileges>\n');
273+
257274
fs.writeFileSync('deploy/ml-config.xml', foo);
258275
} catch (e) {
259276
console.log('failed to update configuration: ' + e.message);
@@ -298,8 +315,8 @@ gulp.task('configGulp', ['init'], function(done) {
298315
configJSON['ml-host'] = settings.marklogicHost;
299316
configJSON['ml-admin-user'] = settings.marklogicAdminUser;
300317
configJSON['ml-admin-pass'] = settings.marklogicAdminPass;
301-
configJSON['ml-app-user'] = settings.marklogicAdminUser; //THIS NEEDS TO CHANGE
302-
configJSON['ml-app-pass'] = settings.marklogicAdminPass; //THIS NEEDS TO CHANGE
318+
configJSON['ml-app-user'] = settings.appName + '-user';
319+
configJSON['ml-app-pass'] = settings.appuserPassword;
303320
configJSON['ml-http-port'] = settings.appPort;
304321
configJSON['node-port'] = settings.nodePort;
305322

@@ -372,6 +389,7 @@ gulp.task('init', ['checkForUpdates'], function (done) {
372389
settings.nodePort = answers.nodePort;
373390
settings.appPort = answers.appPort;
374391
settings.xccPort = answers.xccPort || null;
392+
settings.appName = answers.nameDashed;
375393

376394
getRoxyScript(answers.nameDashed, answers.mlVersion, appType, branch)
377395
.then(runRoxy)

0 commit comments

Comments
 (0)