UserGetter.coffee 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. mongojs = require("../../infrastructure/mongojs")
  2. metrics = require('metrics-sharelatex')
  3. logger = require('logger-sharelatex')
  4. db = mongojs.db
  5. ObjectId = mongojs.ObjectId
  6. { getAffiliations } = require("./UserAffiliationsManager")
  7. module.exports = UserGetter =
  8. getUser: (query, projection, callback = (error, user) ->) ->
  9. if query?.email?
  10. return callback(new Error("Don't use getUser to find user by email"), null)
  11. if arguments.length == 2
  12. callback = projection
  13. projection = {}
  14. if typeof query == "string"
  15. try
  16. query = _id: ObjectId(query)
  17. catch e
  18. return callback(null, null)
  19. else if query instanceof ObjectId
  20. query = _id: query
  21. db.users.findOne query, projection, callback
  22. getUserEmail: (userId, callback = (error, email) ->) ->
  23. @getUser userId, { email: 1 }, (error, user) ->
  24. callback(error, user?.email)
  25. getUserFullEmails: (userId, callback = (error, emails) ->) ->
  26. @getUser userId, { email: 1, emails: 1 }, (error, user) ->
  27. return callback error if error?
  28. return callback new Error('User not Found') unless user
  29. getAffiliations userId, (error, affiliationsData) ->
  30. return callback error if error?
  31. callback null, decorateFullEmails(user.email, user.emails, affiliationsData)
  32. getUserByMainEmail: (email, projection, callback = (error, user) ->) ->
  33. email = email.trim()
  34. if arguments.length == 2
  35. callback = projection
  36. projection = {}
  37. db.users.findOne email: email, projection, callback
  38. getUserByAnyEmail: (email, projection, callback = (error, user) ->) ->
  39. email = email.trim()
  40. if arguments.length == 2
  41. callback = projection
  42. projection = {}
  43. # $exists: true MUST be set to use the partial index
  44. query = emails: { $exists: true }, 'emails.email': email
  45. db.users.findOne query, projection, (error, user) =>
  46. return callback(error, user) if error? or user?
  47. # While multiple emails are being rolled out, check for the main email as
  48. # well
  49. @getUserByMainEmail email, projection, callback
  50. getUsers: (user_ids, projection, callback = (error, users) ->) ->
  51. try
  52. user_ids = user_ids.map (u) -> ObjectId(u.toString())
  53. catch error
  54. return callback error
  55. db.users.find { _id: { $in: user_ids} }, projection, callback
  56. getUserOrUserStubById: (user_id, projection, callback = (error, user) ->) ->
  57. try
  58. query = _id: ObjectId(user_id.toString())
  59. catch e
  60. return callback(new Error(e))
  61. db.users.findOne query, projection, (error, user) ->
  62. return callback(error) if error?
  63. return callback(null, user) if user?
  64. db.userstubs.findOne query, projection, callback
  65. # check for duplicate email address. This is also enforced at the DB level
  66. ensureUniqueEmailAddress: (newEmail, callback) ->
  67. @getUserByAnyEmail newEmail, (error, user) ->
  68. return callback(message: 'alread_exists') if user?
  69. callback(error)
  70. decorateFullEmails = (defaultEmail, emailsData, affiliationsData) ->
  71. emailsData.map (emailData) ->
  72. emailData.default = emailData.email == defaultEmail
  73. affiliation = affiliationsData.find (aff) -> aff.email == emailData.email
  74. if affiliation?
  75. { institution, inferred, role, department } = affiliation
  76. emailData.affiliation = { institution, inferred, role, department }
  77. else
  78. emailsData.affiliation = null
  79. emailData
  80. [
  81. 'getUser',
  82. 'getUserEmail',
  83. 'getUserByMainEmail',
  84. 'getUserByAnyEmail',
  85. 'getUsers',
  86. 'getUserOrUserStubById',
  87. 'ensureUniqueEmailAddress',
  88. ].map (method) ->
  89. metrics.timeAsyncMethod UserGetter, method, 'mongo.UserGetter', logger