summaryrefslogtreecommitdiff
path: root/jstests/sharding/auth_repl.js
blob: b806090fc3adbe87ad806a6c0a38d5ed8751ad87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Multiple users cannot be authenticated on one connection within a session.
TestData.disableImplicitSessions = true;

var replTest = new ReplSetTest({nodes: 3, useHostName: false, keyFile: 'jstests/libs/key1'});
replTest.startSet({oplogSize: 10});
replTest.initiate();
replTest.awaitSecondaryNodes();

var nodeCount = replTest.nodes.length;
var primary = replTest.getPrimary();

// Setup the database using replSet connection before setting the authentication
var conn = new Mongo(replTest.getURL());
var testDB = conn.getDB('test');
var adminDB = conn.getDB('admin');
var testColl = testDB.user;

// Setup the cached connection for primary and secondary in DBClientReplicaSet
// before setting up authentication
assert.commandWorked(adminDB.runCommand({replSetGetStatus: 1}));

conn.setSecondaryOk();
assert.commandWorked(adminDB.runCommand({replSetGetStatus: 1}));

// Add admin user using direct connection to primary to simulate connection from remote host
var priAdminDB = primary.getDB('admin');
priAdminDB.createUser({user: 'user', pwd: 'user', roles: jsTest.adminUserRoles},
                      {w: nodeCount, wtimeout: 30000});
priAdminDB.auth('user', 'user');

var priTestDB = primary.getDB('test');
priTestDB.createUser({user: 'a', pwd: 'a', roles: jsTest.basicUserRoles},
                     {w: nodeCount, wtimeout: 30000});

// Authenticate the replSet connection
assert.eq(1, testDB.auth('a', 'a'));

jsTest.log('Sending an authorized query that should be ok');
assert.commandWorked(testColl.insert({x: 1}, {writeConcern: {w: nodeCount}}));

conn.setSecondaryOk();
doc = testColl.findOne();
assert(doc != null);

doc = testColl.find().readPref('secondary').next();
assert(doc != null);

conn.setSecondaryOk(false);
doc = testColl.findOne();
assert(doc != null);

var queryToPriShouldFail = function() {
    conn.setSecondaryOk(false);

    assert.throws(function() {
        testColl.findOne();
    });

    // should still not work even after retrying
    assert.throws(function() {
        testColl.findOne();
    });
};

var queryToSecShouldFail = function() {
    conn.setSecondaryOk();

    assert.throws(function() {
        testColl.findOne();
    });

    // should still not work even after retrying
    assert.throws(function() {
        testColl.findOne();
    });

    // Query to secondary using readPref
    assert.throws(function() {
        testColl.find().readPref('secondary').next();
    });

    // should still not work even after retrying
    assert.throws(function() {
        testColl.find().readPref('secondary').next();
    });
};

assert(testDB.logout().ok);

jsTest.log('Sending an unauthorized query that should fail');
queryToPriShouldFail();
queryToSecShouldFail();

// Repeat logout test, with secondary first, then primary
assert.eq(1, testDB.auth('a', 'a'));
assert(testDB.logout().ok);

// re-initialize the underlying connections to primary and secondary
jsTest.log('Sending an unauthorized query that should still fail');
queryToSecShouldFail();
queryToPriShouldFail();

// Repeat logout test, now with the cached secondary down
assert.eq(1, testDB.auth('a', 'a'));

// Find out the current cached secondary in the repl connection
conn.setSecondaryOk();
var serverInfo = testColl.find().readPref('secondary').explain().serverInfo;
var secNodeIdx = -1;
var secPortStr = serverInfo.port.toString();

for (var x = 0; x < nodeCount; x++) {
    var nodePortStr = replTest.nodes[x].host.split(':')[1];

    if (nodePortStr == secPortStr) {
        secNodeIdx = x;
    }
}

assert(secNodeIdx >= 0);  // test sanity check

// Kill the cached secondary
replTest.stop(secNodeIdx, 15, {auth: {user: 'user', pwd: 'user'}});

assert(testDB.logout().ok);

replTest.restart(secNodeIdx);
replTest.awaitSecondaryNodes();

jsTest.log('Sending an unauthorized query after restart that should still fail');
queryToSecShouldFail();
queryToPriShouldFail();

replTest.stopSet();