StaticServerForbidSymlinksTests.coffee 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. should = require('chai').should()
  2. SandboxedModule = require('sandboxed-module')
  3. assert = require('assert')
  4. path = require('path')
  5. sinon = require('sinon')
  6. modulePath = path.join __dirname, "../../../app/js/StaticServerForbidSymlinks"
  7. expect = require("chai").expect
  8. describe "StaticServerForbidSymlinks", ->
  9. beforeEach ->
  10. @settings =
  11. path:
  12. compilesDir: "/compiles/here"
  13. @fs = {}
  14. @ForbidSymlinks = SandboxedModule.require modulePath, requires:
  15. "settings-sharelatex":@settings
  16. "logger-sharelatex":
  17. log:->
  18. warn:->
  19. error:->
  20. "fs":@fs
  21. @dummyStatic = (rootDir, options) ->
  22. return (req, res, next) ->
  23. # console.log "dummyStatic serving file", rootDir, "called with", req.url
  24. # serve it
  25. next()
  26. @StaticServerForbidSymlinks = @ForbidSymlinks @dummyStatic, @settings.path.compilesDir
  27. @req =
  28. params:
  29. project_id:"12345"
  30. @res = {}
  31. @req.url = "/12345/output.pdf"
  32. describe "sending a normal file through", ->
  33. beforeEach ->
  34. @fs.realpath = sinon.stub().callsArgWith(1, null, "#{@settings.path.compilesDir}/#{@req.params.project_id}/output.pdf")
  35. it "should call next", (done)->
  36. @res.sendStatus = (resCode)->
  37. resCode.should.equal 200
  38. done()
  39. @StaticServerForbidSymlinks @req, @res, done
  40. describe "with a missing file", ->
  41. beforeEach ->
  42. @fs.realpath = sinon.stub().callsArgWith(1, {code: 'ENOENT'}, "#{@settings.path.compilesDir}/#{@req.params.project_id}/unknown.pdf")
  43. it "should send a 404", (done)->
  44. @res.sendStatus = (resCode)->
  45. resCode.should.equal 404
  46. done()
  47. @StaticServerForbidSymlinks @req, @res
  48. describe "with a symlink file", ->
  49. beforeEach ->
  50. @fs.realpath = sinon.stub().callsArgWith(1, null, "/etc/#{@req.params.project_id}/output.pdf")
  51. it "should send a 404", (done)->
  52. @res.sendStatus = (resCode)->
  53. resCode.should.equal 404
  54. done()
  55. @StaticServerForbidSymlinks @req, @res
  56. describe "with a relative file", ->
  57. beforeEach ->
  58. @req.url = "/12345/../67890/output.pdf"
  59. it "should send a 404", (done)->
  60. @res.sendStatus = (resCode)->
  61. resCode.should.equal 404
  62. done()
  63. @StaticServerForbidSymlinks @req, @res
  64. describe "with a unnormalized file containing .", ->
  65. beforeEach ->
  66. @req.url = "/12345/foo/./output.pdf"
  67. it "should send a 404", (done)->
  68. @res.sendStatus = (resCode)->
  69. resCode.should.equal 404
  70. done()
  71. @StaticServerForbidSymlinks @req, @res
  72. describe "with a file containing an empty path", ->
  73. beforeEach ->
  74. @req.url = "/12345/foo//output.pdf"
  75. it "should send a 404", (done)->
  76. @res.sendStatus = (resCode)->
  77. resCode.should.equal 404
  78. done()
  79. @StaticServerForbidSymlinks @req, @res
  80. describe "with a non-project file", ->
  81. beforeEach ->
  82. @req.url = "/.foo/output.pdf"
  83. it "should send a 404", (done)->
  84. @res.sendStatus = (resCode)->
  85. resCode.should.equal 404
  86. done()
  87. @StaticServerForbidSymlinks @req, @res
  88. describe "with a file outside the compiledir", ->
  89. beforeEach ->
  90. @req.url = "/../bar/output.pdf"
  91. it "should send a 404", (done)->
  92. @res.sendStatus = (resCode)->
  93. resCode.should.equal 404
  94. done()
  95. @StaticServerForbidSymlinks @req, @res
  96. describe "with a file with no leading /", ->
  97. beforeEach ->
  98. @req.url = "./../bar/output.pdf"
  99. it "should send a 404", (done)->
  100. @res.sendStatus = (resCode)->
  101. resCode.should.equal 404
  102. done()
  103. @StaticServerForbidSymlinks @req, @res
  104. describe "with a github style path", ->
  105. beforeEach ->
  106. @req.url = "/henryoswald-latex_example/output/output.log"
  107. @fs.realpath = sinon.stub().callsArgWith(1, null, "#{@settings.path.compilesDir}/henryoswald-latex_example/output/output.log")
  108. it "should call next", (done)->
  109. @res.sendStatus = (resCode)->
  110. resCode.should.equal 200
  111. done()
  112. @StaticServerForbidSymlinks @req, @res, done
  113. describe "with an error from fs.realpath", ->
  114. beforeEach ->
  115. @fs.realpath = sinon.stub().callsArgWith(1, "error")
  116. it "should send a 500", (done)->
  117. @res.sendStatus = (resCode)->
  118. resCode.should.equal 500
  119. done()
  120. @StaticServerForbidSymlinks @req, @res