LaunchpadControllerTests.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. /* eslint-disable
  2. max-len,
  3. no-return-assign,
  4. no-unused-vars,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. const SandboxedModule = require('sandboxed-module')
  14. const assert = require('assert')
  15. require('chai').should()
  16. const { expect } = require('chai')
  17. const sinon = require('sinon')
  18. const { ObjectId } = require('mongojs')
  19. const modulePath = require('path').join(
  20. __dirname,
  21. '../../../app/src/LaunchpadController.js'
  22. )
  23. describe('LaunchpadController', function() {
  24. beforeEach(function() {
  25. this.user = {
  26. _id: '323123',
  27. first_name: 'fn',
  28. last_name: 'ln',
  29. save: sinon.stub().callsArgWith(0)
  30. }
  31. this.User = {}
  32. this.LaunchpadController = SandboxedModule.require(modulePath, {
  33. globals: {
  34. console: console
  35. },
  36. requires: {
  37. 'settings-sharelatex': (this.Settings = {}),
  38. 'logger-sharelatex': (this.Logger = {
  39. log() {},
  40. warn() {},
  41. err() {},
  42. error() {}
  43. }),
  44. 'metrics-sharelatex': (this.Metrics = {}),
  45. '../../../../app/src/Features/User/UserRegistrationHandler': (this.UserRegistrationHandler = {}),
  46. '../../../../app/src/Features/Email/EmailHandler': (this.EmailHandler = {}),
  47. '../../../../app/src/Features/User/UserGetter': (this.UserGetter = {}),
  48. '../../../../app/src/models/User': { User: this.User },
  49. '../../../../app/src/Features/Authentication/AuthenticationController': (this.AuthenticationController = {})
  50. }
  51. })
  52. this.email = 'bob@smith.com'
  53. this.req = {
  54. query: {},
  55. body: {},
  56. session: {}
  57. }
  58. this.res = {
  59. render: sinon.stub(),
  60. redirect: sinon.stub(),
  61. send: sinon.stub(),
  62. sendStatus: sinon.stub()
  63. }
  64. return (this.next = sinon.stub())
  65. })
  66. describe('launchpadPage', function() {
  67. beforeEach(function() {
  68. this._atLeastOneAdminExists = sinon.stub(
  69. this.LaunchpadController,
  70. '_atLeastOneAdminExists'
  71. )
  72. return (this.AuthenticationController.setRedirectInSession = sinon.stub())
  73. })
  74. afterEach(function() {
  75. return this._atLeastOneAdminExists.restore()
  76. })
  77. describe('when the user is not logged in', function() {
  78. beforeEach(function() {
  79. this.AuthenticationController.getSessionUser = sinon
  80. .stub()
  81. .returns(null)
  82. return (this.res.render = sinon.stub())
  83. })
  84. describe('when there are no admins', function() {
  85. beforeEach(function() {
  86. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  87. return this.LaunchpadController.launchpadPage(
  88. this.req,
  89. this.res,
  90. this.next
  91. )
  92. })
  93. it('should render the launchpad page', function() {
  94. const viewPath = require('path').join(
  95. __dirname,
  96. '../../../app/views/launchpad'
  97. )
  98. this.res.render.callCount.should.equal(1)
  99. return this.res.render
  100. .calledWith(viewPath, {
  101. adminUserExists: false,
  102. authMethod: 'local'
  103. })
  104. .should.equal(true)
  105. })
  106. })
  107. describe('when there is at least one admin', function() {
  108. beforeEach(function() {
  109. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  110. return this.LaunchpadController.launchpadPage(
  111. this.req,
  112. this.res,
  113. this.next
  114. )
  115. })
  116. it('should redirect to login page', function() {
  117. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  118. 1
  119. )
  120. this.res.redirect.calledWith('/login').should.equal(true)
  121. })
  122. it('should not render the launchpad page', function() {
  123. return this.res.render.callCount.should.equal(0)
  124. })
  125. })
  126. })
  127. describe('when the user is logged in', function() {
  128. beforeEach(function() {
  129. this.user = {
  130. _id: 'abcd',
  131. email: 'abcd@example.com'
  132. }
  133. this.AuthenticationController.getSessionUser = sinon
  134. .stub()
  135. .returns(this.user)
  136. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  137. this.res.render = sinon.stub()
  138. return (this.res.redirect = sinon.stub())
  139. })
  140. describe('when the user is an admin', function() {
  141. beforeEach(function() {
  142. this.UserGetter.getUser = sinon
  143. .stub()
  144. .callsArgWith(2, null, { isAdmin: true })
  145. return this.LaunchpadController.launchpadPage(
  146. this.req,
  147. this.res,
  148. this.next
  149. )
  150. })
  151. it('should render the launchpad page', function() {
  152. const viewPath = require('path').join(
  153. __dirname,
  154. '../../../app/views/launchpad'
  155. )
  156. this.res.render.callCount.should.equal(1)
  157. return this.res.render
  158. .calledWith(viewPath, {
  159. wsUrl: undefined,
  160. adminUserExists: true,
  161. authMethod: 'local'
  162. })
  163. .should.equal(true)
  164. })
  165. })
  166. describe('when the user is not an admin', function() {
  167. beforeEach(function() {
  168. this.UserGetter.getUser = sinon
  169. .stub()
  170. .callsArgWith(2, null, { isAdmin: false })
  171. return this.LaunchpadController.launchpadPage(
  172. this.req,
  173. this.res,
  174. this.next
  175. )
  176. })
  177. it('should redirect to restricted page', function() {
  178. this.res.redirect.callCount.should.equal(1)
  179. return this.res.redirect.calledWith('/restricted').should.equal(true)
  180. })
  181. })
  182. })
  183. })
  184. describe('_atLeastOneAdminExists', function() {
  185. describe('when there are no admins', function() {
  186. beforeEach(function() {
  187. return (this.UserGetter.getUser = sinon
  188. .stub()
  189. .callsArgWith(2, null, null))
  190. })
  191. it('should callback with false', function(done) {
  192. return this.LaunchpadController._atLeastOneAdminExists(
  193. (err, exists) => {
  194. expect(err).to.equal(null)
  195. expect(exists).to.equal(false)
  196. return done()
  197. }
  198. )
  199. })
  200. })
  201. describe('when there are some admins', function() {
  202. beforeEach(function() {
  203. return (this.UserGetter.getUser = sinon
  204. .stub()
  205. .callsArgWith(2, null, { _id: 'abcd' }))
  206. })
  207. it('should callback with true', function(done) {
  208. return this.LaunchpadController._atLeastOneAdminExists(
  209. (err, exists) => {
  210. expect(err).to.equal(null)
  211. expect(exists).to.equal(true)
  212. return done()
  213. }
  214. )
  215. })
  216. })
  217. describe('when getUser produces an error', function() {
  218. beforeEach(function() {
  219. return (this.UserGetter.getUser = sinon
  220. .stub()
  221. .callsArgWith(2, new Error('woops')))
  222. })
  223. it('should produce an error', function(done) {
  224. return this.LaunchpadController._atLeastOneAdminExists(
  225. (err, exists) => {
  226. expect(err).to.not.equal(null)
  227. expect(err).to.be.instanceof(Error)
  228. expect(exists).to.equal(undefined)
  229. return done()
  230. }
  231. )
  232. })
  233. })
  234. })
  235. describe('sendTestEmail', function() {
  236. beforeEach(function() {
  237. this.EmailHandler.sendEmail = sinon.stub().callsArgWith(2, null)
  238. this.req.body.email = 'someone@example.com'
  239. this.res.sendStatus = sinon.stub()
  240. return (this.next = sinon.stub())
  241. })
  242. it('should produce a 201 response', function() {
  243. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  244. this.res.sendStatus.callCount.should.equal(1)
  245. return this.res.sendStatus.calledWith(201).should.equal(true)
  246. })
  247. it('should not call next with an error', function() {
  248. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  249. return this.next.callCount.should.equal(0)
  250. })
  251. it('should have called sendEmail', function() {
  252. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  253. this.EmailHandler.sendEmail.callCount.should.equal(1)
  254. return this.EmailHandler.sendEmail
  255. .calledWith('testEmail')
  256. .should.equal(true)
  257. })
  258. describe('when sendEmail produces an error', function() {
  259. beforeEach(function() {
  260. return (this.EmailHandler.sendEmail = sinon
  261. .stub()
  262. .callsArgWith(2, new Error('woops')))
  263. })
  264. it('should call next with an error', function() {
  265. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  266. this.next.callCount.should.equal(1)
  267. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  268. })
  269. })
  270. describe('when no email address is supplied', function() {
  271. beforeEach(function() {
  272. return (this.req.body.email = undefined)
  273. })
  274. it('should produce a 400 response', function() {
  275. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  276. this.res.sendStatus.callCount.should.equal(1)
  277. return this.res.sendStatus.calledWith(400).should.equal(true)
  278. })
  279. })
  280. })
  281. describe('registerAdmin', function() {
  282. beforeEach(function() {
  283. return (this._atLeastOneAdminExists = sinon.stub(
  284. this.LaunchpadController,
  285. '_atLeastOneAdminExists'
  286. ))
  287. })
  288. afterEach(function() {
  289. return this._atLeastOneAdminExists.restore()
  290. })
  291. describe('when all goes well', function() {
  292. beforeEach(function() {
  293. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  294. this.email = 'someone@example.com'
  295. this.password = 'a_really_bad_password'
  296. this.req.body.email = this.email
  297. this.req.body.password = this.password
  298. this.user = {
  299. _id: 'abcdef',
  300. email: this.email
  301. }
  302. this.UserRegistrationHandler.registerNewUser = sinon
  303. .stub()
  304. .callsArgWith(1, null, this.user)
  305. this.User.update = sinon.stub().callsArgWith(2, null)
  306. this.AuthenticationController.setRedirectInSession = sinon.stub()
  307. this.res.json = sinon.stub()
  308. this.next = sinon.stub()
  309. return this.LaunchpadController.registerAdmin(
  310. this.req,
  311. this.res,
  312. this.next
  313. )
  314. })
  315. it('should send back a json response', function() {
  316. this.res.json.callCount.should.equal(1)
  317. return expect(this.res.json.lastCall.args[0].email).to.equal(this.email)
  318. })
  319. it('should have checked for existing admins', function() {
  320. return this._atLeastOneAdminExists.callCount.should.equal(1)
  321. })
  322. it('should have called registerNewUser', function() {
  323. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  324. return this.UserRegistrationHandler.registerNewUser
  325. .calledWith({ email: this.email, password: this.password })
  326. .should.equal(true)
  327. })
  328. it('should have updated the user to make them an admin', function() {
  329. this.User.update.callCount.should.equal(1)
  330. return this.User.update
  331. .calledWithMatch(
  332. { _id: this.user._id },
  333. {
  334. $set: {
  335. isAdmin: true,
  336. emails: [{ email: this.user.email }]
  337. }
  338. }
  339. )
  340. .should.equal(true)
  341. })
  342. it('should have set a redirect in session', function() {
  343. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  344. 1
  345. )
  346. return this.AuthenticationController.setRedirectInSession
  347. .calledWith(this.req, '/launchpad')
  348. .should.equal(true)
  349. })
  350. })
  351. describe('when no email is supplied', function() {
  352. beforeEach(function() {
  353. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  354. this.email = undefined
  355. this.password = 'a_really_bad_password'
  356. this.req.body.email = this.email
  357. this.req.body.password = this.password
  358. this.user = {
  359. _id: 'abcdef',
  360. email: this.email
  361. }
  362. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  363. this.User.update = sinon.stub()
  364. this.AuthenticationController.setRedirectInSession = sinon.stub()
  365. this.res.sendStatus = sinon.stub()
  366. this.next = sinon.stub()
  367. return this.LaunchpadController.registerAdmin(
  368. this.req,
  369. this.res,
  370. this.next
  371. )
  372. })
  373. it('should send a 400 response', function() {
  374. this.res.sendStatus.callCount.should.equal(1)
  375. return this.res.sendStatus.calledWith(400).should.equal(true)
  376. })
  377. it('should not check for existing admins', function() {
  378. return this._atLeastOneAdminExists.callCount.should.equal(0)
  379. })
  380. it('should not call registerNewUser', function() {
  381. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  382. 0
  383. )
  384. })
  385. })
  386. describe('when no password is supplied', function() {
  387. beforeEach(function() {
  388. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  389. this.email = 'someone@example.com'
  390. this.password = undefined
  391. this.req.body.email = this.email
  392. this.req.body.password = this.password
  393. this.user = {
  394. _id: 'abcdef',
  395. email: this.email
  396. }
  397. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  398. this.User.update = sinon.stub()
  399. this.AuthenticationController.setRedirectInSession = sinon.stub()
  400. this.res.sendStatus = sinon.stub()
  401. this.next = sinon.stub()
  402. return this.LaunchpadController.registerAdmin(
  403. this.req,
  404. this.res,
  405. this.next
  406. )
  407. })
  408. it('should send a 400 response', function() {
  409. this.res.sendStatus.callCount.should.equal(1)
  410. return this.res.sendStatus.calledWith(400).should.equal(true)
  411. })
  412. it('should not check for existing admins', function() {
  413. return this._atLeastOneAdminExists.callCount.should.equal(0)
  414. })
  415. it('should not call registerNewUser', function() {
  416. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  417. 0
  418. )
  419. })
  420. })
  421. describe('when there are already existing admins', function() {
  422. beforeEach(function() {
  423. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  424. this.email = 'someone@example.com'
  425. this.password = 'a_really_bad_password'
  426. this.req.body.email = this.email
  427. this.req.body.password = this.password
  428. this.user = {
  429. _id: 'abcdef',
  430. email: this.email
  431. }
  432. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  433. this.User.update = sinon.stub()
  434. this.AuthenticationController.setRedirectInSession = sinon.stub()
  435. this.res.sendStatus = sinon.stub()
  436. this.next = sinon.stub()
  437. return this.LaunchpadController.registerAdmin(
  438. this.req,
  439. this.res,
  440. this.next
  441. )
  442. })
  443. it('should send a 403 response', function() {
  444. this.res.sendStatus.callCount.should.equal(1)
  445. return this.res.sendStatus.calledWith(403).should.equal(true)
  446. })
  447. it('should not call registerNewUser', function() {
  448. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  449. 0
  450. )
  451. })
  452. })
  453. describe('when checking admins produces an error', function() {
  454. beforeEach(function() {
  455. this._atLeastOneAdminExists.callsArgWith(0, new Error('woops'))
  456. this.email = 'someone@example.com'
  457. this.password = 'a_really_bad_password'
  458. this.req.body.email = this.email
  459. this.req.body.password = this.password
  460. this.user = {
  461. _id: 'abcdef',
  462. email: this.email
  463. }
  464. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  465. this.User.update = sinon.stub()
  466. this.AuthenticationController.setRedirectInSession = sinon.stub()
  467. this.res.sendStatus = sinon.stub()
  468. this.next = sinon.stub()
  469. return this.LaunchpadController.registerAdmin(
  470. this.req,
  471. this.res,
  472. this.next
  473. )
  474. })
  475. it('should call next with an error', function() {
  476. this.next.callCount.should.equal(1)
  477. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  478. })
  479. it('should have checked for existing admins', function() {
  480. return this._atLeastOneAdminExists.callCount.should.equal(1)
  481. })
  482. it('should not call registerNewUser', function() {
  483. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  484. 0
  485. )
  486. })
  487. })
  488. describe('when registerNewUser produces an error', function() {
  489. beforeEach(function() {
  490. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  491. this.email = 'someone@example.com'
  492. this.password = 'a_really_bad_password'
  493. this.req.body.email = this.email
  494. this.req.body.password = this.password
  495. this.user = {
  496. _id: 'abcdef',
  497. email: this.email
  498. }
  499. this.UserRegistrationHandler.registerNewUser = sinon
  500. .stub()
  501. .callsArgWith(1, new Error('woops'))
  502. this.User.update = sinon.stub()
  503. this.AuthenticationController.setRedirectInSession = sinon.stub()
  504. this.res.json = sinon.stub()
  505. this.next = sinon.stub()
  506. return this.LaunchpadController.registerAdmin(
  507. this.req,
  508. this.res,
  509. this.next
  510. )
  511. })
  512. it('should call next with an error', function() {
  513. this.next.callCount.should.equal(1)
  514. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  515. })
  516. it('should have checked for existing admins', function() {
  517. return this._atLeastOneAdminExists.callCount.should.equal(1)
  518. })
  519. it('should have called registerNewUser', function() {
  520. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  521. return this.UserRegistrationHandler.registerNewUser
  522. .calledWith({ email: this.email, password: this.password })
  523. .should.equal(true)
  524. })
  525. it('should not call update', function() {
  526. return this.User.update.callCount.should.equal(0)
  527. })
  528. })
  529. describe('when user update produces an error', function() {
  530. beforeEach(function() {
  531. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  532. this.email = 'someone@example.com'
  533. this.password = 'a_really_bad_password'
  534. this.req.body.email = this.email
  535. this.req.body.password = this.password
  536. this.user = {
  537. _id: 'abcdef',
  538. email: this.email
  539. }
  540. this.UserRegistrationHandler.registerNewUser = sinon
  541. .stub()
  542. .callsArgWith(1, null, this.user)
  543. this.User.update = sinon.stub().callsArgWith(2, new Error('woops'))
  544. this.AuthenticationController.setRedirectInSession = sinon.stub()
  545. this.res.json = sinon.stub()
  546. this.next = sinon.stub()
  547. return this.LaunchpadController.registerAdmin(
  548. this.req,
  549. this.res,
  550. this.next
  551. )
  552. })
  553. it('should call next with an error', function() {
  554. this.next.callCount.should.equal(1)
  555. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  556. })
  557. it('should have checked for existing admins', function() {
  558. return this._atLeastOneAdminExists.callCount.should.equal(1)
  559. })
  560. it('should have called registerNewUser', function() {
  561. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  562. return this.UserRegistrationHandler.registerNewUser
  563. .calledWith({ email: this.email, password: this.password })
  564. .should.equal(true)
  565. })
  566. })
  567. describe('when overleaf', function() {
  568. beforeEach(function() {
  569. this.Settings.overleaf = { one: 1 }
  570. this.Settings.createV1AccountOnLogin = true
  571. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  572. this.email = 'someone@example.com'
  573. this.password = 'a_really_bad_password'
  574. this.req.body.email = this.email
  575. this.req.body.password = this.password
  576. this.user = {
  577. _id: 'abcdef',
  578. email: this.email
  579. }
  580. this.UserRegistrationHandler.registerNewUser = sinon
  581. .stub()
  582. .callsArgWith(1, null, this.user)
  583. this.User.update = sinon.stub().callsArgWith(2, null)
  584. this.AuthenticationController.setRedirectInSession = sinon.stub()
  585. this.UserGetter.getUser = sinon
  586. .stub()
  587. .callsArgWith(1, null, { _id: '1234' })
  588. this.res.json = sinon.stub()
  589. this.next = sinon.stub()
  590. return this.LaunchpadController.registerAdmin(
  591. this.req,
  592. this.res,
  593. this.next
  594. )
  595. })
  596. it('should send back a json response', function() {
  597. this.res.json.callCount.should.equal(1)
  598. return expect(this.res.json.lastCall.args[0].email).to.equal(this.email)
  599. })
  600. it('should have checked for existing admins', function() {
  601. return this._atLeastOneAdminExists.callCount.should.equal(1)
  602. })
  603. it('should have called registerNewUser', function() {
  604. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  605. return this.UserRegistrationHandler.registerNewUser
  606. .calledWith({ email: this.email, password: this.password })
  607. .should.equal(true)
  608. })
  609. it('should have updated the user to make them an admin', function() {
  610. return this.User.update
  611. .calledWith(
  612. { _id: this.user._id },
  613. {
  614. $set: {
  615. isAdmin: true,
  616. emails: [{ email: this.user.email }]
  617. }
  618. }
  619. )
  620. .should.equal(true)
  621. })
  622. it('should have set a redirect in session', function() {
  623. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  624. 1
  625. )
  626. return this.AuthenticationController.setRedirectInSession
  627. .calledWith(this.req, '/launchpad')
  628. .should.equal(true)
  629. })
  630. })
  631. })
  632. describe('registerExternalAuthAdmin', function() {
  633. beforeEach(function() {
  634. this.Settings.ldap = { one: 1 }
  635. return (this._atLeastOneAdminExists = sinon.stub(
  636. this.LaunchpadController,
  637. '_atLeastOneAdminExists'
  638. ))
  639. })
  640. afterEach(function() {
  641. return this._atLeastOneAdminExists.restore()
  642. })
  643. describe('when all goes well', function() {
  644. beforeEach(function() {
  645. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  646. this.email = 'someone@example.com'
  647. this.req.body.email = this.email
  648. this.user = {
  649. _id: 'abcdef',
  650. email: this.email
  651. }
  652. this.UserRegistrationHandler.registerNewUser = sinon
  653. .stub()
  654. .callsArgWith(1, null, this.user)
  655. this.User.update = sinon.stub().callsArgWith(2, null)
  656. this.AuthenticationController.setRedirectInSession = sinon.stub()
  657. this.res.json = sinon.stub()
  658. this.next = sinon.stub()
  659. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  660. this.req,
  661. this.res,
  662. this.next
  663. )
  664. })
  665. it('should send back a json response', function() {
  666. this.res.json.callCount.should.equal(1)
  667. return expect(this.res.json.lastCall.args[0].email).to.equal(this.email)
  668. })
  669. it('should have checked for existing admins', function() {
  670. return this._atLeastOneAdminExists.callCount.should.equal(1)
  671. })
  672. it('should have called registerNewUser', function() {
  673. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  674. return this.UserRegistrationHandler.registerNewUser
  675. .calledWith({
  676. email: this.email,
  677. password: 'password_here',
  678. first_name: this.email,
  679. last_name: ''
  680. })
  681. .should.equal(true)
  682. })
  683. it('should have updated the user to make them an admin', function() {
  684. this.User.update.callCount.should.equal(1)
  685. return this.User.update
  686. .calledWith(
  687. { _id: this.user._id },
  688. {
  689. $set: { isAdmin: true },
  690. emails: [{ email: this.user.email }]
  691. }
  692. )
  693. .should.equal(true)
  694. })
  695. it('should have set a redirect in session', function() {
  696. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  697. 1
  698. )
  699. return this.AuthenticationController.setRedirectInSession
  700. .calledWith(this.req, '/launchpad')
  701. .should.equal(true)
  702. })
  703. })
  704. describe('when the authMethod is invalid', function() {
  705. beforeEach(function() {
  706. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  707. this.email = undefined
  708. this.req.body.email = this.email
  709. this.user = {
  710. _id: 'abcdef',
  711. email: this.email
  712. }
  713. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  714. this.User.update = sinon.stub()
  715. this.AuthenticationController.setRedirectInSession = sinon.stub()
  716. this.res.sendStatus = sinon.stub()
  717. this.next = sinon.stub()
  718. return this.LaunchpadController.registerExternalAuthAdmin(
  719. 'NOTAVALIDAUTHMETHOD'
  720. )(this.req, this.res, this.next)
  721. })
  722. it('should send a 403 response', function() {
  723. this.res.sendStatus.callCount.should.equal(1)
  724. return this.res.sendStatus.calledWith(403).should.equal(true)
  725. })
  726. it('should not check for existing admins', function() {
  727. return this._atLeastOneAdminExists.callCount.should.equal(0)
  728. })
  729. it('should not call registerNewUser', function() {
  730. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  731. 0
  732. )
  733. })
  734. })
  735. describe('when no email is supplied', function() {
  736. beforeEach(function() {
  737. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  738. this.email = undefined
  739. this.req.body.email = this.email
  740. this.user = {
  741. _id: 'abcdef',
  742. email: this.email
  743. }
  744. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  745. this.User.update = sinon.stub()
  746. this.AuthenticationController.setRedirectInSession = sinon.stub()
  747. this.res.sendStatus = sinon.stub()
  748. this.next = sinon.stub()
  749. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  750. this.req,
  751. this.res,
  752. this.next
  753. )
  754. })
  755. it('should send a 400 response', function() {
  756. this.res.sendStatus.callCount.should.equal(1)
  757. return this.res.sendStatus.calledWith(400).should.equal(true)
  758. })
  759. it('should not check for existing admins', function() {
  760. return this._atLeastOneAdminExists.callCount.should.equal(0)
  761. })
  762. it('should not call registerNewUser', function() {
  763. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  764. 0
  765. )
  766. })
  767. })
  768. describe('when there are already existing admins', function() {
  769. beforeEach(function() {
  770. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  771. this.email = 'someone@example.com'
  772. this.req.body.email = this.email
  773. this.user = {
  774. _id: 'abcdef',
  775. email: this.email
  776. }
  777. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  778. this.User.update = sinon.stub()
  779. this.AuthenticationController.setRedirectInSession = sinon.stub()
  780. this.res.sendStatus = sinon.stub()
  781. this.next = sinon.stub()
  782. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  783. this.req,
  784. this.res,
  785. this.next
  786. )
  787. })
  788. it('should send a 403 response', function() {
  789. this.res.sendStatus.callCount.should.equal(1)
  790. return this.res.sendStatus.calledWith(403).should.equal(true)
  791. })
  792. it('should not call registerNewUser', function() {
  793. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  794. 0
  795. )
  796. })
  797. })
  798. describe('when checking admins produces an error', function() {
  799. beforeEach(function() {
  800. this._atLeastOneAdminExists.callsArgWith(0, new Error('woops'))
  801. this.email = 'someone@example.com'
  802. this.req.body.email = this.email
  803. this.user = {
  804. _id: 'abcdef',
  805. email: this.email
  806. }
  807. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  808. this.User.update = sinon.stub()
  809. this.AuthenticationController.setRedirectInSession = sinon.stub()
  810. this.res.sendStatus = sinon.stub()
  811. this.next = sinon.stub()
  812. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  813. this.req,
  814. this.res,
  815. this.next
  816. )
  817. })
  818. it('should call next with an error', function() {
  819. this.next.callCount.should.equal(1)
  820. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  821. })
  822. it('should have checked for existing admins', function() {
  823. return this._atLeastOneAdminExists.callCount.should.equal(1)
  824. })
  825. it('should not call registerNewUser', function() {
  826. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  827. 0
  828. )
  829. })
  830. })
  831. describe('when registerNewUser produces an error', function() {
  832. beforeEach(function() {
  833. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  834. this.email = 'someone@example.com'
  835. this.req.body.email = this.email
  836. this.user = {
  837. _id: 'abcdef',
  838. email: this.email
  839. }
  840. this.UserRegistrationHandler.registerNewUser = sinon
  841. .stub()
  842. .callsArgWith(1, new Error('woops'))
  843. this.User.update = sinon.stub()
  844. this.AuthenticationController.setRedirectInSession = sinon.stub()
  845. this.res.json = sinon.stub()
  846. this.next = sinon.stub()
  847. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  848. this.req,
  849. this.res,
  850. this.next
  851. )
  852. })
  853. it('should call next with an error', function() {
  854. this.next.callCount.should.equal(1)
  855. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  856. })
  857. it('should have checked for existing admins', function() {
  858. return this._atLeastOneAdminExists.callCount.should.equal(1)
  859. })
  860. it('should have called registerNewUser', function() {
  861. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  862. return this.UserRegistrationHandler.registerNewUser
  863. .calledWith({
  864. email: this.email,
  865. password: 'password_here',
  866. first_name: this.email,
  867. last_name: ''
  868. })
  869. .should.equal(true)
  870. })
  871. it('should not call update', function() {
  872. return this.User.update.callCount.should.equal(0)
  873. })
  874. })
  875. describe('when user update produces an error', function() {
  876. beforeEach(function() {
  877. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  878. this.email = 'someone@example.com'
  879. this.req.body.email = this.email
  880. this.user = {
  881. _id: 'abcdef',
  882. email: this.email
  883. }
  884. this.UserRegistrationHandler.registerNewUser = sinon
  885. .stub()
  886. .callsArgWith(1, null, this.user)
  887. this.User.update = sinon.stub().callsArgWith(2, new Error('woops'))
  888. this.AuthenticationController.setRedirectInSession = sinon.stub()
  889. this.res.json = sinon.stub()
  890. this.next = sinon.stub()
  891. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  892. this.req,
  893. this.res,
  894. this.next
  895. )
  896. })
  897. it('should call next with an error', function() {
  898. this.next.callCount.should.equal(1)
  899. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  900. })
  901. it('should have checked for existing admins', function() {
  902. return this._atLeastOneAdminExists.callCount.should.equal(1)
  903. })
  904. it('should have called registerNewUser', function() {
  905. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  906. return this.UserRegistrationHandler.registerNewUser
  907. .calledWith({
  908. email: this.email,
  909. password: 'password_here',
  910. first_name: this.email,
  911. last_name: ''
  912. })
  913. .should.equal(true)
  914. })
  915. })
  916. })
  917. })