SudoModeHandlerTests.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /* eslint-disable
  2. handle-callback-err,
  3. max-len,
  4. no-return-assign,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS102: Remove unnecessary code created because of implicit returns
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. const SandboxedModule = require('sandboxed-module')
  15. const assert = require('assert')
  16. require('chai').should()
  17. const { expect } = require('chai')
  18. const sinon = require('sinon')
  19. const modulePath = require('path').join(
  20. __dirname,
  21. '../../../../app/src/Features/SudoMode/SudoModeHandler'
  22. )
  23. describe('SudoModeHandler', function() {
  24. beforeEach(function() {
  25. this.userId = 'some_user_id'
  26. this.email = 'someuser@example.com'
  27. this.user = {
  28. _id: this.userId,
  29. email: this.email
  30. }
  31. this.rclient = { get: sinon.stub(), set: sinon.stub(), del: sinon.stub() }
  32. this.RedisWrapper = { client: () => this.rclient }
  33. return (this.SudoModeHandler = SandboxedModule.require(modulePath, {
  34. globals: {
  35. console: console
  36. },
  37. requires: {
  38. '../../infrastructure/RedisWrapper': this.RedisWrapper,
  39. 'logger-sharelatex': (this.logger = {
  40. log: sinon.stub(),
  41. err: sinon.stub()
  42. }),
  43. '../Authentication/AuthenticationManager': (this.AuthenticationManager = {}),
  44. 'settings-sharelatex': (this.Settings = {}),
  45. '../V1/V1Handler': (this.V1Handler = { authWithV1: sinon.stub() }),
  46. '../User/UserGetter': (this.UserGetter = { getUser: sinon.stub() })
  47. }
  48. }))
  49. })
  50. describe('_buildKey', function() {
  51. it('should build a properly formed key', function() {
  52. return expect(this.SudoModeHandler._buildKey('123')).to.equal(
  53. 'SudoMode:{123}'
  54. )
  55. })
  56. })
  57. describe('activateSudoMode', function() {
  58. beforeEach(function() {
  59. return (this.call = cb => {
  60. return this.SudoModeHandler.activateSudoMode(this.userId, cb)
  61. })
  62. })
  63. describe('when all goes well', function() {
  64. beforeEach(function() {
  65. return (this.rclient.set = sinon.stub().callsArgWith(4, null))
  66. })
  67. it('should not produce an error', function(done) {
  68. return this.call(err => {
  69. expect(err).to.equal(null)
  70. return done()
  71. })
  72. })
  73. it('should set a value in redis', function(done) {
  74. return this.call(err => {
  75. expect(this.rclient.set.callCount).to.equal(1)
  76. expect(
  77. this.rclient.set.calledWith(
  78. 'SudoMode:{some_user_id}',
  79. '1',
  80. 'EX',
  81. 60 * 60
  82. )
  83. ).to.equal(true)
  84. return done()
  85. })
  86. })
  87. })
  88. describe('when user id is not supplied', function() {
  89. beforeEach(function() {
  90. return (this.call = cb => {
  91. return this.SudoModeHandler.activateSudoMode(null, cb)
  92. })
  93. })
  94. it('should produce an error', function(done) {
  95. return this.call(err => {
  96. expect(err).to.not.equal(null)
  97. expect(err).to.be.instanceof(Error)
  98. return done()
  99. })
  100. })
  101. it('should not set value in redis', function(done) {
  102. return this.call(err => {
  103. expect(this.rclient.set.callCount).to.equal(0)
  104. return done()
  105. })
  106. })
  107. })
  108. describe('when rclient.set produces an error', function() {
  109. beforeEach(function() {
  110. return (this.rclient.set = sinon
  111. .stub()
  112. .callsArgWith(4, new Error('woops')))
  113. })
  114. it('should produce an error', function(done) {
  115. return this.call(err => {
  116. expect(err).to.not.equal(null)
  117. expect(err).to.be.instanceof(Error)
  118. return done()
  119. })
  120. })
  121. })
  122. })
  123. describe('clearSudoMode', function() {
  124. beforeEach(function() {
  125. this.rclient.del = sinon.stub().callsArgWith(1, null)
  126. return (this.call = cb => {
  127. return this.SudoModeHandler.clearSudoMode(this.userId, cb)
  128. })
  129. })
  130. it('should not produce an error', function(done) {
  131. return this.call(err => {
  132. expect(err).to.equal(null)
  133. return done()
  134. })
  135. })
  136. it('should delete key from redis', function(done) {
  137. return this.call(err => {
  138. expect(this.rclient.del.callCount).to.equal(1)
  139. expect(this.rclient.del.calledWith('SudoMode:{some_user_id}')).to.equal(
  140. true
  141. )
  142. return done()
  143. })
  144. })
  145. describe('when rclient.del produces an error', function() {
  146. beforeEach(function() {
  147. return (this.rclient.del = sinon
  148. .stub()
  149. .callsArgWith(1, new Error('woops')))
  150. })
  151. it('should produce an error', function(done) {
  152. return this.call(err => {
  153. expect(err).to.not.equal(null)
  154. expect(err).to.be.instanceof(Error)
  155. return done()
  156. })
  157. })
  158. })
  159. describe('when user id is not supplied', function() {
  160. beforeEach(function() {
  161. return (this.call = cb => {
  162. return this.SudoModeHandler.clearSudoMode(null, cb)
  163. })
  164. })
  165. it('should produce an error', function(done) {
  166. return this.call(err => {
  167. expect(err).to.not.equal(null)
  168. expect(err).to.be.instanceof(Error)
  169. return done()
  170. })
  171. })
  172. it('should not delete value in redis', function(done) {
  173. return this.call(err => {
  174. expect(this.rclient.del.callCount).to.equal(0)
  175. return done()
  176. })
  177. })
  178. })
  179. })
  180. describe('authenticate', function() {
  181. beforeEach(function() {
  182. return (this.AuthenticationManager.authenticate = sinon
  183. .stub()
  184. .callsArgWith(2, null, this.user))
  185. })
  186. it('should call AuthenticationManager.authenticate', function(done) {
  187. return this.SudoModeHandler.authenticate(
  188. this.email,
  189. 'password',
  190. (err, user) => {
  191. expect(err).to.not.exist
  192. expect(user).to.exist
  193. expect(user).to.deep.equal(this.user)
  194. expect(this.AuthenticationManager.authenticate.callCount).to.equal(1)
  195. return done()
  196. }
  197. )
  198. })
  199. })
  200. describe('isSudoModeActive', function() {
  201. beforeEach(function() {
  202. return (this.call = cb => {
  203. return this.SudoModeHandler.isSudoModeActive(this.userId, cb)
  204. })
  205. })
  206. describe('when sudo-mode is active for that user', function() {
  207. beforeEach(function() {
  208. return (this.rclient.get = sinon.stub().callsArgWith(1, null, '1'))
  209. })
  210. it('should not produce an error', function(done) {
  211. return this.call((err, isActive) => {
  212. expect(err).to.equal(null)
  213. return done()
  214. })
  215. })
  216. it('should get the value from redis', function(done) {
  217. return this.call((err, isActive) => {
  218. expect(this.rclient.get.callCount).to.equal(1)
  219. expect(
  220. this.rclient.get.calledWith('SudoMode:{some_user_id}')
  221. ).to.equal(true)
  222. return done()
  223. })
  224. })
  225. it('should produce a true result', function(done) {
  226. return this.call((err, isActive) => {
  227. expect(isActive).to.equal(true)
  228. return done()
  229. })
  230. })
  231. })
  232. describe('when sudo-mode is not active for that user', function() {
  233. beforeEach(function() {
  234. return (this.rclient.get = sinon.stub().callsArgWith(1, null, null))
  235. })
  236. it('should not produce an error', function(done) {
  237. return this.call((err, isActive) => {
  238. expect(err).to.equal(null)
  239. return done()
  240. })
  241. })
  242. it('should get the value from redis', function(done) {
  243. return this.call((err, isActive) => {
  244. expect(this.rclient.get.callCount).to.equal(1)
  245. expect(
  246. this.rclient.get.calledWith('SudoMode:{some_user_id}')
  247. ).to.equal(true)
  248. return done()
  249. })
  250. })
  251. it('should produce a false result', function(done) {
  252. return this.call((err, isActive) => {
  253. expect(isActive).to.equal(false)
  254. return done()
  255. })
  256. })
  257. })
  258. describe('when rclient.get produces an error', function() {
  259. beforeEach(function() {
  260. return (this.rclient.get = sinon
  261. .stub()
  262. .callsArgWith(1, new Error('woops')))
  263. })
  264. it('should produce an error', function(done) {
  265. return this.call((err, isActive) => {
  266. expect(err).to.not.equal(null)
  267. expect(err).to.be.instanceof(Error)
  268. expect(isActive).to.be.oneOf([null, undefined])
  269. return done()
  270. })
  271. })
  272. })
  273. describe('when user id is not supplied', function() {
  274. beforeEach(function() {
  275. return (this.call = cb => {
  276. return this.SudoModeHandler.isSudoModeActive(null, cb)
  277. })
  278. })
  279. it('should produce an error', function(done) {
  280. return this.call(err => {
  281. expect(err).to.not.equal(null)
  282. expect(err).to.be.instanceof(Error)
  283. return done()
  284. })
  285. })
  286. it('should not get value in redis', function(done) {
  287. return this.call(err => {
  288. expect(this.rclient.get.callCount).to.equal(0)
  289. return done()
  290. })
  291. })
  292. })
  293. })
  294. })