// Test for SERVER-9129 // Verify global scope data does not persist past logout or auth. // NOTE: Each test case covers 3 state transitions: // no auth -> auth user 'a' // auth user 'a' -> auth user 'b' // auth user 'b' -> logout // // These transitions are tested for $where and MapReduce. (function() { 'use strict'; const conn = MongoRunner.runMongod(); const test = conn.getDB("test"); // insert a single document and add two test users assert.writeOK(test.foo.insert({a: 1})); assert.eq(1, test.foo.findOne().a); test.createUser({user: 'a', pwd: 'a', roles: jsTest.basicUserRoles}); test.createUser({user: 'b', pwd: 'b', roles: jsTest.basicUserRoles}); function missingOrEquals(string) { return 'function() { ' + 'var global = function(){return this;}.call();' // Uncomment the next line when debugging. // + 'print(global.hasOwnProperty("someGlobal") ? someGlobal : "MISSING" );' + 'return !global.hasOwnProperty("someGlobal")' + ' || someGlobal == unescape("' + escape(string) + '");' + '}()'; } // test $where function testWhere() { // set the global variable 'someGlobal' before authenticating test.foo.findOne({$where: 'someGlobal = "noUsers";'}); // test new user auth causes scope to be cleared assert(test.auth('a', 'a')); assert.eq( 1, test.foo.count({$where: 'return ' + missingOrEquals('a')}), "$where: Auth user 'a"); // test auth as another user causes scope to be cleared test.foo.findOne({$where: 'someGlobal = "a";'}); test.logout(); test.auth('b', 'b'); assert(test.foo.count({$where: 'return ' + missingOrEquals('a&b')}), "$where: Auth user 'b'"); // test user logout causes scope to be cleared test.foo.findOne({$where: 'someGlobal = "a&b";'}); test.logout(); assert(test.foo.count({$where: 'return ' + missingOrEquals('noUsers')}), "$where: log out"); } testWhere(); testWhere(); function testMapReduce() { function mapSet(string) { return Function('someGlobal = "' + string + '"'); } function mapGet(string) { return Function('assert(' + missingOrEquals(string) + ')'); } function reduce(k, v) { // Do nothing } function setGlobalInMap(string) { test.foo.mapReduce(mapSet(string), reduce, {out: {inline: 1}}); } function getGlobalFromMap(string) { test.foo.mapReduce(mapGet(string), reduce, {out: {inline: 1}}); } // set the global variable 'someGlobal' before authenticating setGlobalInMap('noUsers'); // test new user auth causes scope to be cleared assert(test.auth('a', 'a')); assert.doesNotThrow(function() { getGlobalFromMap('a'); }, [], "M/R: Auth user 'a'"); // test auth as another user causes scope to be cleared setGlobalInMap('a'); test.logout(); assert(test.auth('b', 'b')); assert.doesNotThrow(function() { getGlobalFromMap('a&b'); }, [], "M/R: Auth user 'b'"); // test user logout causes scope to be cleared setGlobalInMap('a&b'); test.logout(); assert.doesNotThrow(function() { getGlobalFromMap('noUsers'); }, [], "M/R: Log out"); } testMapReduce(); testMapReduce(); MongoRunner.stopMongod(conn); })();