You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					100 lines
				
				2.6 KiB
			
		
		
			
		
	
	
					100 lines
				
				2.6 KiB
			| 
											3 years ago
										 | 'use strict'; | ||
|  | 
 | ||
|  | const Aspect = require('./operation').Aspect; | ||
|  | const CommandOperation = require('./command'); | ||
|  | const defineAspects = require('./operation').defineAspects; | ||
|  | const crypto = require('crypto'); | ||
|  | const handleCallback = require('../utils').handleCallback; | ||
|  | const toError = require('../utils').toError; | ||
|  | const emitWarning = require('../utils').emitWarning; | ||
|  | 
 | ||
|  | class AddUserOperation extends CommandOperation { | ||
|  |   constructor(db, username, password, options) { | ||
|  |     super(db, options); | ||
|  | 
 | ||
|  |     this.username = username; | ||
|  |     this.password = password; | ||
|  |   } | ||
|  | 
 | ||
|  |   _buildCommand() { | ||
|  |     const db = this.db; | ||
|  |     const username = this.username; | ||
|  |     const password = this.password; | ||
|  |     const options = this.options; | ||
|  | 
 | ||
|  |     // Get additional values
 | ||
|  |     let roles = []; | ||
|  |     if (Array.isArray(options.roles)) roles = options.roles; | ||
|  |     if (typeof options.roles === 'string') roles = [options.roles]; | ||
|  | 
 | ||
|  |     // If not roles defined print deprecated message
 | ||
|  |     // TODO: handle deprecation properly
 | ||
|  |     if (roles.length === 0) { | ||
|  |       emitWarning('Creating a user without roles is deprecated in MongoDB >= 2.6'); | ||
|  |     } | ||
|  | 
 | ||
|  |     // Check the db name and add roles if needed
 | ||
|  |     if ( | ||
|  |       (db.databaseName.toLowerCase() === 'admin' || options.dbName === 'admin') && | ||
|  |       !Array.isArray(options.roles) | ||
|  |     ) { | ||
|  |       roles = ['root']; | ||
|  |     } else if (!Array.isArray(options.roles)) { | ||
|  |       roles = ['dbOwner']; | ||
|  |     } | ||
|  | 
 | ||
|  |     const digestPassword = db.s.topology.lastIsMaster().maxWireVersion >= 7; | ||
|  | 
 | ||
|  |     let userPassword = password; | ||
|  | 
 | ||
|  |     if (!digestPassword) { | ||
|  |       // Use node md5 generator
 | ||
|  |       const md5 = crypto.createHash('md5'); | ||
|  |       // Generate keys used for authentication
 | ||
|  |       md5.update(username + ':mongo:' + password); | ||
|  |       userPassword = md5.digest('hex'); | ||
|  |     } | ||
|  | 
 | ||
|  |     // Build the command to execute
 | ||
|  |     const command = { | ||
|  |       createUser: username, | ||
|  |       customData: options.customData || {}, | ||
|  |       roles: roles, | ||
|  |       digestPassword | ||
|  |     }; | ||
|  | 
 | ||
|  |     // No password
 | ||
|  |     if (typeof password === 'string') { | ||
|  |       command.pwd = userPassword; | ||
|  |     } | ||
|  | 
 | ||
|  |     return command; | ||
|  |   } | ||
|  | 
 | ||
|  |   execute(callback) { | ||
|  |     const options = this.options; | ||
|  | 
 | ||
|  |     // Error out if digestPassword set
 | ||
|  |     if (options.digestPassword != null) { | ||
|  |       return callback( | ||
|  |         toError( | ||
|  |           "The digestPassword option is not supported via add_user. Please use db.command('createUser', ...) instead for this option." | ||
|  |         ) | ||
|  |       ); | ||
|  |     } | ||
|  | 
 | ||
|  |     // Attempt to execute auth command
 | ||
|  |     super.execute((err, r) => { | ||
|  |       if (!err) { | ||
|  |         return handleCallback(callback, err, r); | ||
|  |       } | ||
|  | 
 | ||
|  |       return handleCallback(callback, err, null); | ||
|  |     }); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | defineAspects(AddUserOperation, Aspect.WRITE_OPERATION); | ||
|  | 
 | ||
|  | module.exports = AddUserOperation; |