[MediaWiki-commits] [Gerrit] mediawiki...eventstreams[master]: Merge from upstream template/master at a354b0e8bbf88123a6c2f...

2017-02-24 Thread Ottomata (Code Review)
Ottomata has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/339706 )

Change subject: Merge from upstream template/master at 
a354b0e8bbf88123a6c2fe17693435fb1107b794
..

Merge from upstream template/master at a354b0e8bbf88123a6c2fe17693435fb1107b794

Conflicts:
lib/api-util.js
package.json
routes/ex.js
routes/root.js
routes/v1.js

Change-Id: Ia0cc779e5292bde0ffe287b8bc9c901462c5852a
---
A lib/swagger-ui.js
M package.json
M routes/root.js
M spec.template.yaml
4 files changed, 101 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/eventstreams 
refs/changes/06/339706/1

diff --git a/lib/swagger-ui.js b/lib/swagger-ui.js
new file mode 100644
index 000..a4e41c2
--- /dev/null
+++ b/lib/swagger-ui.js
@@ -0,0 +1,79 @@
+'use strict';
+
+
+const BBPromise = require('bluebird');
+const fs = BBPromise.promisifyAll(require('fs'));
+const path = require('path');
+const HTTPError = require('../lib/util.js').HTTPError;
+
+
+// Swagger-ui helpfully exporting the absolute path of its dist directory
+const docRoot = `${require('swagger-ui').dist}/`;
+
+function processRequest(app, req, res) {
+
+const reqPath = req.query.path || '/index.html';
+const filePath = path.join(docRoot, reqPath);
+
+// Disallow relative paths.
+// Test relies on docRoot ending on a slash.
+if (filePath.substring(0, docRoot.length) !== docRoot) {
+throw new HTTPError({
+status: 404,
+type: 'not_found',
+title: 'File not found',
+detail: `${reqPath} could not be found.`
+});
+}
+
+return fs.readFileAsync(filePath)
+.then((body) => {
+if (reqPath === '/index.html') {
+body = body.toString()
+.replace(/((?:src|href)=['"])/g, '$1?doc=')
+// Some self-promotion
+.replace(//,
+`${app.info.name}`)
+.replace(/[^<]*<\/title>/, 
`${app.info.name}`)
+// Replace the default url with ours, switch off validation &
+// limit the size of documents to apply syntax highlighting to
+.replace(/Sorter: "alpha"/, 'Sorter: "alpha", validatorUrl: 
null, ' +
+'highlightSizeThreshold: 1')
+.replace(/docExpansion: "none"/, 'docExpansion: "list"')
+.replace(/ url: url,/, 'url: "/?spec",');
+}
+
+let contentType = 'text/html';
+if (/\.js$/.test(reqPath)) {
+contentType = 'text/javascript';
+body = body.toString()
+.replace(/underscore-min\.map/, 
'?doc=lib/underscore-min.map');
+} else if (/\.png$/.test(reqPath)) {
+contentType = 'image/png';
+} else if (/\.map$/.test(reqPath)) {
+contentType = 'application/json';
+} else if (/\.ttf$/.test(reqPath)) {
+contentType = 'application/x-font-ttf';
+} else if (/\.css$/.test(reqPath)) {
+contentType = 'text/css';
+body = body.toString().replace(/\.\.\/(images|fonts)\//g, 
'?doc=$1/');
+}
+
+res.setHeader('Content-Type', contentType);
+res.setHeader('content-security-policy', "default-src 'none'; " +
+"script-src 'self' 'unsafe-inline'; connect-src *; " +
+"style-src 'self' 'unsafe-inline'; img-src 'self'; 
font-src 'self';");
+res.send(body.toString());
+})
+.catch({ code: 'ENOENT' }, () => {
+res.status(404)
+.type('not_found')
+.send('not found');
+});
+
+}
+
+module.exports = {
+processRequest
+};
+
diff --git a/package.json b/package.json
index 4e1bd94..bf74eab 100644
--- a/package.json
+++ b/package.json
@@ -1,13 +1,20 @@
 {
+<<< HEAD
   "name": "eventstreams",
   "version": "0.0.2",
   "description": "Streaming Wikimedia Events via HTTP SSE",
+===
+  "name": "service-template-node",
+  "version": "0.5.0",
+  "description": "A blueprint for MediaWiki REST API services",
+>>> tmpl/master
   "main": "./app.js",
   "scripts": {
 "start": "service-runner",
-"test": "mocha && nsp check",
+"test": "PREQ_CONNECT_TIMEOUT=15 mocha && nsp check",
 "docker-start": "service-runner docker-start",
 "docker-test": "service-runner docker-test",
+"test-build": "service-runner docker-test && service-runner build 
--deploy-repo --force",
 "coverage": "istanbul cover _mocha -- -R spec"
   },
   "repository": {
@@ -42,6 +49,7 @@
 "js-yaml": "^3.7.0",
 "service-runner": "^2.1.11",
 "swagger-router": "^0.5.5",
+"swagger-ui": "git+https://github.com/wikimedia/swagger-ui#master;,
 "node-rdkafka-statsd": "^0.1.0",
 "kafka-sse": 
"git+https://phabricator.wikimedia.org/diffusion/WKSE/kafkasse.git#v0.0.6;
   },
diff --git a/routes/root.js 

[MediaWiki-commits] [Gerrit] mediawiki...eventstreams[master]: Merge from upstream template/master at a354b0e8bbf88123a6c2f...

2017-02-24 Thread Ottomata (Code Review)
Ottomata has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/339706 )

Change subject: Merge from upstream template/master at 
a354b0e8bbf88123a6c2fe17693435fb1107b794
..


Merge from upstream template/master at a354b0e8bbf88123a6c2fe17693435fb1107b794

Conflicts:
lib/api-util.js
package.json
routes/ex.js
routes/root.js
routes/v1.js

Change-Id: Ia0cc779e5292bde0ffe287b8bc9c901462c5852a
---
A lib/swagger-ui.js
M package.json
M routes/root.js
M spec.template.yaml
4 files changed, 95 insertions(+), 5 deletions(-)

Approvals:
  Ottomata: Verified; Looks good to me, approved



diff --git a/lib/swagger-ui.js b/lib/swagger-ui.js
new file mode 100644
index 000..a4e41c2
--- /dev/null
+++ b/lib/swagger-ui.js
@@ -0,0 +1,79 @@
+'use strict';
+
+
+const BBPromise = require('bluebird');
+const fs = BBPromise.promisifyAll(require('fs'));
+const path = require('path');
+const HTTPError = require('../lib/util.js').HTTPError;
+
+
+// Swagger-ui helpfully exporting the absolute path of its dist directory
+const docRoot = `${require('swagger-ui').dist}/`;
+
+function processRequest(app, req, res) {
+
+const reqPath = req.query.path || '/index.html';
+const filePath = path.join(docRoot, reqPath);
+
+// Disallow relative paths.
+// Test relies on docRoot ending on a slash.
+if (filePath.substring(0, docRoot.length) !== docRoot) {
+throw new HTTPError({
+status: 404,
+type: 'not_found',
+title: 'File not found',
+detail: `${reqPath} could not be found.`
+});
+}
+
+return fs.readFileAsync(filePath)
+.then((body) => {
+if (reqPath === '/index.html') {
+body = body.toString()
+.replace(/((?:src|href)=['"])/g, '$1?doc=')
+// Some self-promotion
+.replace(//,
+`${app.info.name}`)
+.replace(/[^<]*<\/title>/, 
`${app.info.name}`)
+// Replace the default url with ours, switch off validation &
+// limit the size of documents to apply syntax highlighting to
+.replace(/Sorter: "alpha"/, 'Sorter: "alpha", validatorUrl: 
null, ' +
+'highlightSizeThreshold: 1')
+.replace(/docExpansion: "none"/, 'docExpansion: "list"')
+.replace(/ url: url,/, 'url: "/?spec",');
+}
+
+let contentType = 'text/html';
+if (/\.js$/.test(reqPath)) {
+contentType = 'text/javascript';
+body = body.toString()
+.replace(/underscore-min\.map/, 
'?doc=lib/underscore-min.map');
+} else if (/\.png$/.test(reqPath)) {
+contentType = 'image/png';
+} else if (/\.map$/.test(reqPath)) {
+contentType = 'application/json';
+} else if (/\.ttf$/.test(reqPath)) {
+contentType = 'application/x-font-ttf';
+} else if (/\.css$/.test(reqPath)) {
+contentType = 'text/css';
+body = body.toString().replace(/\.\.\/(images|fonts)\//g, 
'?doc=$1/');
+}
+
+res.setHeader('Content-Type', contentType);
+res.setHeader('content-security-policy', "default-src 'none'; " +
+"script-src 'self' 'unsafe-inline'; connect-src *; " +
+"style-src 'self' 'unsafe-inline'; img-src 'self'; 
font-src 'self';");
+res.send(body.toString());
+})
+.catch({ code: 'ENOENT' }, () => {
+res.status(404)
+.type('not_found')
+.send('not found');
+});
+
+}
+
+module.exports = {
+processRequest
+};
+
diff --git a/package.json b/package.json
index 4e1bd94..ff9e48f 100644
--- a/package.json
+++ b/package.json
@@ -5,9 +5,10 @@
   "main": "./app.js",
   "scripts": {
 "start": "service-runner",
-"test": "mocha && nsp check",
+"test": "PREQ_CONNECT_TIMEOUT=15 mocha && nsp check",
 "docker-start": "service-runner docker-start",
 "docker-test": "service-runner docker-test",
+"test-build": "service-runner docker-test && service-runner build 
--deploy-repo --force",
 "coverage": "istanbul cover _mocha -- -R spec"
   },
   "repository": {
@@ -42,6 +43,7 @@
 "js-yaml": "^3.7.0",
 "service-runner": "^2.1.11",
 "swagger-router": "^0.5.5",
+"swagger-ui": "git+https://github.com/wikimedia/swagger-ui#master;,
 "node-rdkafka-statsd": "^0.1.0",
 "kafka-sse": 
"git+https://phabricator.wikimedia.org/diffusion/WKSE/kafkasse.git#v0.0.6;
   },
diff --git a/routes/root.js b/routes/root.js
index 28930cb..42686eb 100644
--- a/routes/root.js
+++ b/routes/root.js
@@ -2,6 +2,7 @@
 
 
 const sUtil = require('../lib/util');
+const swaggerUi = require('../lib/swagger-ui');
 
 
 /**
@@ -31,15 +32,17 @@
 
 /**
  * GET /
- * Main entry point. Currently it only responds if the spec query
+ *