StaticServerForbidSymlinksTests.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /* eslint-disable
  2. no-return-assign,
  3. no-unused-vars,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS102: Remove unnecessary code created because of implicit returns
  10. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  11. */
  12. const should = require('chai').should();
  13. const SandboxedModule = require('sandboxed-module');
  14. const assert = require('assert');
  15. const path = require('path');
  16. const sinon = require('sinon');
  17. const modulePath = path.join(__dirname, "../../../app/js/StaticServerForbidSymlinks");
  18. const { expect } = require("chai");
  19. describe("StaticServerForbidSymlinks", function() {
  20. beforeEach(function() {
  21. this.settings = {
  22. path: {
  23. compilesDir: "/compiles/here"
  24. }
  25. };
  26. this.fs = {};
  27. this.ForbidSymlinks = SandboxedModule.require(modulePath, { requires: {
  28. "settings-sharelatex":this.settings,
  29. "logger-sharelatex": {
  30. log() {},
  31. warn() {},
  32. error() {}
  33. },
  34. "fs":this.fs
  35. }
  36. }
  37. );
  38. this.dummyStatic = (rootDir, options) =>
  39. (req, res, next) =>
  40. // console.log "dummyStatic serving file", rootDir, "called with", req.url
  41. // serve it
  42. next()
  43. ;
  44. this.StaticServerForbidSymlinks = this.ForbidSymlinks(this.dummyStatic, this.settings.path.compilesDir);
  45. this.req = {
  46. params: {
  47. project_id:"12345"
  48. }
  49. };
  50. this.res = {};
  51. return this.req.url = "/12345/output.pdf";
  52. });
  53. describe("sending a normal file through", function() {
  54. beforeEach(function() {
  55. return this.fs.realpath = sinon.stub().callsArgWith(1, null, `${this.settings.path.compilesDir}/${this.req.params.project_id}/output.pdf`);
  56. });
  57. return it("should call next", function(done){
  58. this.res.sendStatus = function(resCode){
  59. resCode.should.equal(200);
  60. return done();
  61. };
  62. return this.StaticServerForbidSymlinks(this.req, this.res, done);
  63. });
  64. });
  65. describe("with a missing file", function() {
  66. beforeEach(function() {
  67. return this.fs.realpath = sinon.stub().callsArgWith(1, {code: 'ENOENT'}, `${this.settings.path.compilesDir}/${this.req.params.project_id}/unknown.pdf`);
  68. });
  69. return it("should send a 404", function(done){
  70. this.res.sendStatus = function(resCode){
  71. resCode.should.equal(404);
  72. return done();
  73. };
  74. return this.StaticServerForbidSymlinks(this.req, this.res);
  75. });
  76. });
  77. describe("with a symlink file", function() {
  78. beforeEach(function() {
  79. return this.fs.realpath = sinon.stub().callsArgWith(1, null, `/etc/${this.req.params.project_id}/output.pdf`);
  80. });
  81. return it("should send a 404", function(done){
  82. this.res.sendStatus = function(resCode){
  83. resCode.should.equal(404);
  84. return done();
  85. };
  86. return this.StaticServerForbidSymlinks(this.req, this.res);
  87. });
  88. });
  89. describe("with a relative file", function() {
  90. beforeEach(function() {
  91. return this.req.url = "/12345/../67890/output.pdf";
  92. });
  93. return it("should send a 404", function(done){
  94. this.res.sendStatus = function(resCode){
  95. resCode.should.equal(404);
  96. return done();
  97. };
  98. return this.StaticServerForbidSymlinks(this.req, this.res);
  99. });
  100. });
  101. describe("with a unnormalized file containing .", function() {
  102. beforeEach(function() {
  103. return this.req.url = "/12345/foo/./output.pdf";
  104. });
  105. return it("should send a 404", function(done){
  106. this.res.sendStatus = function(resCode){
  107. resCode.should.equal(404);
  108. return done();
  109. };
  110. return this.StaticServerForbidSymlinks(this.req, this.res);
  111. });
  112. });
  113. describe("with a file containing an empty path", function() {
  114. beforeEach(function() {
  115. return this.req.url = "/12345/foo//output.pdf";
  116. });
  117. return it("should send a 404", function(done){
  118. this.res.sendStatus = function(resCode){
  119. resCode.should.equal(404);
  120. return done();
  121. };
  122. return this.StaticServerForbidSymlinks(this.req, this.res);
  123. });
  124. });
  125. describe("with a non-project file", function() {
  126. beforeEach(function() {
  127. return this.req.url = "/.foo/output.pdf";
  128. });
  129. return it("should send a 404", function(done){
  130. this.res.sendStatus = function(resCode){
  131. resCode.should.equal(404);
  132. return done();
  133. };
  134. return this.StaticServerForbidSymlinks(this.req, this.res);
  135. });
  136. });
  137. describe("with a file outside the compiledir", function() {
  138. beforeEach(function() {
  139. return this.req.url = "/../bar/output.pdf";
  140. });
  141. return it("should send a 404", function(done){
  142. this.res.sendStatus = function(resCode){
  143. resCode.should.equal(404);
  144. return done();
  145. };
  146. return this.StaticServerForbidSymlinks(this.req, this.res);
  147. });
  148. });
  149. describe("with a file with no leading /", function() {
  150. beforeEach(function() {
  151. return this.req.url = "./../bar/output.pdf";
  152. });
  153. return it("should send a 404", function(done){
  154. this.res.sendStatus = function(resCode){
  155. resCode.should.equal(404);
  156. return done();
  157. };
  158. return this.StaticServerForbidSymlinks(this.req, this.res);
  159. });
  160. });
  161. describe("with a github style path", function() {
  162. beforeEach(function() {
  163. this.req.url = "/henryoswald-latex_example/output/output.log";
  164. return this.fs.realpath = sinon.stub().callsArgWith(1, null, `${this.settings.path.compilesDir}/henryoswald-latex_example/output/output.log`);
  165. });
  166. return it("should call next", function(done){
  167. this.res.sendStatus = function(resCode){
  168. resCode.should.equal(200);
  169. return done();
  170. };
  171. return this.StaticServerForbidSymlinks(this.req, this.res, done);
  172. });
  173. });
  174. return describe("with an error from fs.realpath", function() {
  175. beforeEach(function() {
  176. return this.fs.realpath = sinon.stub().callsArgWith(1, "error");
  177. });
  178. return it("should send a 500", function(done){
  179. this.res.sendStatus = function(resCode){
  180. resCode.should.equal(500);
  181. return done();
  182. };
  183. return this.StaticServerForbidSymlinks(this.req, this.res);
  184. });
  185. });
  186. });