InstitutionsAPI.coffee 4.0 KB

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