add_user.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. 'use strict';
  2. const Aspect = require('./operation').Aspect;
  3. const CommandOperation = require('./command');
  4. const defineAspects = require('./operation').defineAspects;
  5. const crypto = require('crypto');
  6. const handleCallback = require('../utils').handleCallback;
  7. const toError = require('../utils').toError;
  8. const emitWarning = require('../utils').emitWarning;
  9. class AddUserOperation extends CommandOperation {
  10. constructor(db, username, password, options) {
  11. super(db, options);
  12. this.username = username;
  13. this.password = password;
  14. }
  15. _buildCommand() {
  16. const db = this.db;
  17. const username = this.username;
  18. const password = this.password;
  19. const options = this.options;
  20. // Get additional values
  21. let roles = [];
  22. if (Array.isArray(options.roles)) roles = options.roles;
  23. if (typeof options.roles === 'string') roles = [options.roles];
  24. // If not roles defined print deprecated message
  25. // TODO: handle deprecation properly
  26. if (roles.length === 0) {
  27. emitWarning('Creating a user without roles is deprecated in MongoDB >= 2.6');
  28. }
  29. // Check the db name and add roles if needed
  30. if (
  31. (db.databaseName.toLowerCase() === 'admin' || options.dbName === 'admin') &&
  32. !Array.isArray(options.roles)
  33. ) {
  34. roles = ['root'];
  35. } else if (!Array.isArray(options.roles)) {
  36. roles = ['dbOwner'];
  37. }
  38. const digestPassword = db.s.topology.lastIsMaster().maxWireVersion >= 7;
  39. let userPassword = password;
  40. if (!digestPassword) {
  41. // Use node md5 generator
  42. const md5 = crypto.createHash('md5');
  43. // Generate keys used for authentication
  44. md5.update(username + ':mongo:' + password);
  45. userPassword = md5.digest('hex');
  46. }
  47. // Build the command to execute
  48. const command = {
  49. createUser: username,
  50. customData: options.customData || {},
  51. roles: roles,
  52. digestPassword
  53. };
  54. // No password
  55. if (typeof password === 'string') {
  56. command.pwd = userPassword;
  57. }
  58. return command;
  59. }
  60. execute(callback) {
  61. const options = this.options;
  62. // Error out if digestPassword set
  63. if (options.digestPassword != null) {
  64. return callback(
  65. toError(
  66. "The digestPassword option is not supported via add_user. Please use db.command('createUser', ...) instead for this option."
  67. )
  68. );
  69. }
  70. // Attempt to execute auth command
  71. super.execute((err, r) => {
  72. if (!err) {
  73. return handleCallback(callback, err, r);
  74. }
  75. return handleCallback(callback, err, null);
  76. });
  77. }
  78. }
  79. defineAspects(AddUserOperation, Aspect.WRITE_OPERATION);
  80. module.exports = AddUserOperation;