Ohm-Management - Projektarbeit B-ME
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.

plain.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. 'use strict';
  2. var f = require('util').format,
  3. retrieveBSON = require('../connection/utils').retrieveBSON,
  4. Query = require('../connection/commands').Query,
  5. MongoError = require('../error').MongoError;
  6. var BSON = retrieveBSON(),
  7. Binary = BSON.Binary;
  8. var AuthSession = function(db, username, password) {
  9. this.db = db;
  10. this.username = username;
  11. this.password = password;
  12. };
  13. AuthSession.prototype.equal = function(session) {
  14. return (
  15. session.db === this.db &&
  16. session.username === this.username &&
  17. session.password === this.password
  18. );
  19. };
  20. /**
  21. * Creates a new Plain authentication mechanism
  22. * @class
  23. * @return {Plain} A cursor instance
  24. */
  25. var Plain = function(bson) {
  26. this.bson = bson;
  27. this.authStore = [];
  28. };
  29. /**
  30. * Authenticate
  31. * @method
  32. * @param {{Server}|{ReplSet}|{Mongos}} server Topology the authentication method is being called on
  33. * @param {[]Connections} connections Connections to authenticate using this authenticator
  34. * @param {string} db Name of the database
  35. * @param {string} username Username
  36. * @param {string} password Password
  37. * @param {authResultCallback} callback The callback to return the result from the authentication
  38. * @return {object}
  39. */
  40. Plain.prototype.auth = function(server, connections, db, username, password, callback) {
  41. var self = this;
  42. // Total connections
  43. var count = connections.length;
  44. if (count === 0) return callback(null, null);
  45. // Valid connections
  46. var numberOfValidConnections = 0;
  47. var errorObject = null;
  48. // For each connection we need to authenticate
  49. while (connections.length > 0) {
  50. // Execute MongoCR
  51. var execute = function(connection) {
  52. // Create payload
  53. var payload = new Binary(f('\x00%s\x00%s', username, password));
  54. // Let's start the sasl process
  55. var command = {
  56. saslStart: 1,
  57. mechanism: 'PLAIN',
  58. payload: payload,
  59. autoAuthorize: 1
  60. };
  61. // Let's start the process
  62. server(
  63. connection,
  64. new Query(self.bson, '$external.$cmd', command, {
  65. numberToSkip: 0,
  66. numberToReturn: 1
  67. }),
  68. function(err, r) {
  69. // Adjust count
  70. count = count - 1;
  71. // If we have an error
  72. if (err) {
  73. errorObject = err;
  74. } else if (r.result['$err']) {
  75. errorObject = r.result;
  76. } else if (r.result['errmsg']) {
  77. errorObject = r.result;
  78. } else {
  79. numberOfValidConnections = numberOfValidConnections + 1;
  80. }
  81. // We have authenticated all connections
  82. if (count === 0 && numberOfValidConnections > 0) {
  83. // Store the auth details
  84. addAuthSession(self.authStore, new AuthSession(db, username, password));
  85. // Return correct authentication
  86. callback(null, true);
  87. } else if (count === 0) {
  88. if (errorObject == null)
  89. errorObject = new MongoError(f('failed to authenticate using mongocr'));
  90. callback(errorObject, false);
  91. }
  92. }
  93. );
  94. };
  95. var _execute = function(_connection) {
  96. process.nextTick(function() {
  97. execute(_connection);
  98. });
  99. };
  100. _execute(connections.shift());
  101. }
  102. };
  103. // Add to store only if it does not exist
  104. var addAuthSession = function(authStore, session) {
  105. var found = false;
  106. for (var i = 0; i < authStore.length; i++) {
  107. if (authStore[i].equal(session)) {
  108. found = true;
  109. break;
  110. }
  111. }
  112. if (!found) authStore.push(session);
  113. };
  114. /**
  115. * Remove authStore credentials
  116. * @method
  117. * @param {string} db Name of database we are removing authStore details about
  118. * @return {object}
  119. */
  120. Plain.prototype.logout = function(dbName) {
  121. this.authStore = this.authStore.filter(function(x) {
  122. return x.db !== dbName;
  123. });
  124. };
  125. /**
  126. * Re authenticate pool
  127. * @method
  128. * @param {{Server}|{ReplSet}|{Mongos}} server Topology the authentication method is being called on
  129. * @param {[]Connections} connections Connections to authenticate using this authenticator
  130. * @param {authResultCallback} callback The callback to return the result from the authentication
  131. * @return {object}
  132. */
  133. Plain.prototype.reauthenticate = function(server, connections, callback) {
  134. var authStore = this.authStore.slice(0);
  135. var count = authStore.length;
  136. if (count === 0) return callback(null, null);
  137. // Iterate over all the auth details stored
  138. for (var i = 0; i < authStore.length; i++) {
  139. this.auth(
  140. server,
  141. connections,
  142. authStore[i].db,
  143. authStore[i].username,
  144. authStore[i].password,
  145. function(err) {
  146. count = count - 1;
  147. // Done re-authenticating
  148. if (count === 0) {
  149. callback(err, null);
  150. }
  151. }
  152. );
  153. }
  154. };
  155. /**
  156. * This is a result from a authentication strategy
  157. *
  158. * @callback authResultCallback
  159. * @param {error} error An error object. Set to null if no error present
  160. * @param {boolean} result The result of the authentication process
  161. */
  162. module.exports = Plain;