InstitutionsAPI.coffee 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. logger = require("logger-sharelatex")
  2. metrics = require("metrics-sharelatex")
  3. settings = require "settings-sharelatex"
  4. request = require "request"
  5. module.exports = InstitutionsAPI =
  6. getInstitutionAffiliations: (institutionId, callback = (error, body) ->) ->
  7. makeAffiliationRequest {
  8. method: 'GET'
  9. path: "/api/v2/institutions/#{institutionId.toString()}/affiliations"
  10. defaultErrorMessage: "Couldn't get institution affiliations"
  11. }, (error, body) -> callback(error, body or [])
  12. getInstitutionLicences: (institutionId, startDate, endDate, lag, callback = (error, body) ->) ->
  13. makeAffiliationRequest {
  14. method: 'GET'
  15. path: "/api/v2/institutions/#{institutionId.toString()}/institution_licences"
  16. body: {start_date: startDate, end_date: endDate, lag}
  17. defaultErrorMessage: "Couldn't get institution licences"
  18. }, callback
  19. getUserAffiliations: (userId, callback = (error, body) ->) ->
  20. makeAffiliationRequest {
  21. method: 'GET'
  22. path: "/api/v2/users/#{userId.toString()}/affiliations"
  23. defaultErrorMessage: "Couldn't get user affiliations"
  24. }, (error, body) -> callback(error, body or [])
  25. addAffiliation: (userId, email, affiliationOptions, callback) ->
  26. unless callback? # affiliationOptions is optional
  27. callback = affiliationOptions
  28. affiliationOptions = {}
  29. { university, department, role, confirmedAt } = affiliationOptions
  30. makeAffiliationRequest {
  31. method: 'POST'
  32. path: "/api/v2/users/#{userId.toString()}/affiliations"
  33. body: { email, university, department, role, confirmedAt }
  34. defaultErrorMessage: "Couldn't create affiliation"
  35. }, callback
  36. removeAffiliation: (userId, email, callback = (error) ->) ->
  37. makeAffiliationRequest {
  38. method: 'POST'
  39. path: "/api/v2/users/#{userId.toString()}/affiliations/remove"
  40. body: { email }
  41. extraSuccessStatusCodes: [404] # `Not Found` responses are considered successful
  42. defaultErrorMessage: "Couldn't remove affiliation"
  43. }, callback
  44. endorseAffiliation: (userId, email, role, department, callback = (error) ->) ->
  45. makeAffiliationRequest {
  46. method: 'POST'
  47. path: "/api/v2/users/#{userId.toString()}/affiliations/endorse"
  48. body: { email, role, department }
  49. defaultErrorMessage: "Couldn't endorse affiliation"
  50. }, callback
  51. deleteAffiliations: (userId, callback = (error) ->) ->
  52. makeAffiliationRequest {
  53. method: 'DELETE'
  54. path: "/api/v2/users/#{userId.toString()}/affiliations"
  55. defaultErrorMessage: "Couldn't delete affiliations"
  56. }, callback
  57. makeAffiliationRequest = (requestOptions, callback = (error) ->) ->
  58. return callback(null) unless settings?.apis?.v1?.url # service is not configured
  59. requestOptions.extraSuccessStatusCodes ||= []
  60. request {
  61. method: requestOptions.method
  62. url: "#{settings.apis.v1.url}#{requestOptions.path}"
  63. body: requestOptions.body
  64. auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass }
  65. json: true,
  66. timeout: 20 * 1000
  67. }, (error, response, body) ->
  68. return callback(error) if error?
  69. isSuccess = 200 <= response.statusCode < 300
  70. isSuccess ||= response.statusCode in requestOptions.extraSuccessStatusCodes
  71. unless isSuccess
  72. if body?.errors
  73. errorMessage = "#{response.statusCode}: #{body.errors}"
  74. else
  75. errorMessage = "#{requestOptions.defaultErrorMessage}: #{response.statusCode}"
  76. logger.err path: requestOptions.path, body: requestOptions.body, errorMessage
  77. return callback(new Error(errorMessage))
  78. callback(null, body)
  79. [
  80. 'getInstitutionAffiliations'
  81. 'getUserAffiliations',
  82. 'addAffiliation',
  83. 'removeAffiliation',
  84. ].map (method) ->
  85. metrics.timeAsyncMethod(
  86. InstitutionsAPI, method, 'mongo.InstitutionsAPI', logger
  87. )