external-account.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. const debug = require('debug')('crowi:models:external-account');
  2. const mongoose = require('mongoose');
  3. const uniqueValidator = require('mongoose-unique-validator');
  4. const ObjectId = mongoose.Schema.Types.ObjectId;
  5. /*
  6. * define schema
  7. */
  8. const schema = new mongoose.Schema({
  9. providerType: { type: String, required: true },
  10. accountId: { type: String, required: true },
  11. user: { type: ObjectId, ref: 'User', required: true },
  12. createdAt: { type: Date, default: Date.now, required: true },
  13. });
  14. // compound index
  15. schema.index({ providerType: 1, accountId: 1 });
  16. // apply plugins
  17. schema.plugin(uniqueValidator);
  18. /**
  19. * ExternalAccount Class
  20. *
  21. * @class ExternalAccount
  22. */
  23. class ExternalAccount {
  24. static set crowi(crowi) {
  25. this._crowi = crowi;
  26. }
  27. static get crowi() {
  28. return this._crowi;
  29. }
  30. /**
  31. * get the populated user entity
  32. *
  33. * @returns Promise<User>
  34. * @memberof ExternalAccount
  35. */
  36. getPopulatedUser() {
  37. return this.populate('user').execPopulate()
  38. .then((account) => {
  39. return account.user;
  40. })
  41. }
  42. /**
  43. * find an account or register if not found
  44. *
  45. * @static
  46. * @param {string} providerType
  47. * @param {string} accountId
  48. * @param {object} usernameToBeRegistered the username of User entity that will be created when accountId is not found
  49. * @returns {Promise<ExternalAccount>}
  50. * @memberof ExternalAccount
  51. */
  52. static findOrRegister(providerType, accountId, usernameToBeRegistered) {
  53. return this.findOne({ providerType, accountId })
  54. .then((account) => {
  55. // found
  56. if (account != null) {
  57. debug(`ExternalAccount '${accountId}' is found `, account);
  58. return account;
  59. }
  60. // not found
  61. else {
  62. debug(`ExternalAccount '${accountId}' is not found, it is going to be registered.`);
  63. const User = ExternalAccount.crowi.model('User');
  64. return User.count({username: usernameToBeRegistered})
  65. .then((count) => {
  66. // throw Exception when count is not zero
  67. if (count > 0) {
  68. throw new DuplicatedUsernameException(`username '${usernameToBeRegistered}' has already been existed`);
  69. }
  70. // create user with STATUS_ACTIVE
  71. return User.createUser('', usernameToBeRegistered, undefined, undefined, undefined, User.STATUS_ACTIVE);
  72. })
  73. .then((user) => {
  74. return this.create({ providerType: 'ldap', accountId, user: user._id });
  75. });
  76. }
  77. });
  78. }
  79. }
  80. /**
  81. * The Exception class thrown when User.username is duplicated when creating user
  82. *
  83. * @class DuplicatedUsernameException
  84. */
  85. class DuplicatedUsernameException {
  86. constructor(message) {
  87. this.name = this.constructor.name;
  88. this.message = message;
  89. }
  90. }
  91. module.exports = function(crowi) {
  92. ExternalAccount.crowi = crowi;
  93. schema.loadClass(ExternalAccount);
  94. return mongoose.model('ExternalAccount', schema);
  95. }