summaryrefslogtreecommitdiff
path: root/jstests/tool/dumprestore_auth3.js
blob: 8fb70d2a91b72ad5788b121cbd8066307df97b20 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// dumprestore_auth3.js
// Tests that mongodump and mongorestore properly handle access control information when doing
// single-db dumps and restores

// Runs the tool with the given name against the given mongod.
function runTool(toolName, mongod, options) {
    var opts = {host: mongod.host};
    Object.extend(opts, options);
    MongoRunner.runMongoTool(toolName, opts);
}

var dumpRestoreAuth3 = function(backup_role, restore_role) {

    var mongod = MongoRunner.runMongod();
    var admindb = mongod.getDB("admin");
    var db = mongod.getDB("foo");

    jsTestLog("Creating Admin user & initial data");
    admindb.createUser({user: 'root', pwd: 'pass', roles: ['root']});
    admindb.createUser({user: 'backup', pwd: 'pass', roles: ['backup']});
    admindb.createUser({user: 'restore', pwd: 'pass', roles: ['restore']});
    admindb.createRole({role: "dummyRole", roles: [], privileges: []});
    db.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
    db.createRole({role: 'role', roles: [], privileges: []});
    var backupActions = ['find'];
    db.createRole({
        role: 'backupFooChester',
        privileges: [{resource: {db: 'foo', collection: 'chester'}, actions: backupActions}],
        roles: []
    });
    db.createUser({user: 'backupFooChester', pwd: 'pass', roles: ['backupFooChester']});

    var userCount = db.getUsers().length;
    var rolesCount = db.getRoles().length;
    var adminUsersCount = admindb.getUsers().length;
    var adminRolesCount = admindb.getRoles().length;
    var systemUsersCount = admindb.system.users.count();
    var systemVersionCount = admindb.system.version.count();

    db.bar.insert({a: 1});

    assert.eq(1, db.bar.findOne().a);
    assert.eq(userCount, db.getUsers().length, "setup");
    assert.eq(rolesCount, db.getRoles().length, "setup2");
    assert.eq(adminUsersCount, admindb.getUsers().length, "setup3");
    assert.eq(adminRolesCount, admindb.getRoles().length, "setup4");
    assert.eq(systemUsersCount, admindb.system.users.count(), "setup5");
    assert.eq(systemVersionCount, admindb.system.version.count(), "system version");
    assert.eq(1, admindb.system.users.count({user: "restore"}), "Restore user is missing");
    assert.eq(1, admindb.system.users.count({user: "backup"}), "Backup user is missing");
    var versionDoc = admindb.system.version.findOne();

    jsTestLog("Dump foo database without dumping user data");
    var dumpDir = MongoRunner.getAndPrepareDumpDirectory("dumprestore_auth3");
    runTool("mongodump", mongod, {out: dumpDir, db: "foo"});
    db = mongod.getDB('foo');

    db.dropDatabase();
    db.dropAllUsers();
    db.dropAllRoles();

    jsTestLog("Restore foo database from dump that doesn't contain user data ");
    // This test depends on W=0 to mask unique index violations.
    // This should be fixed once we implement TOOLS-341
    runTool("mongorestore",
            mongod,
            {dir: dumpDir + "foo/", db: 'foo', restoreDbUsersAndRoles: "", writeConcern: "0"});

    db = mongod.getDB('foo');

    assert.soon(function() {
        return db.bar.findOne();
    }, "no data after restore");
    assert.eq(1, db.bar.findOne().a);
    assert.eq(0, db.getUsers().length, "Restore created users somehow");
    assert.eq(0, db.getRoles().length, "Restore created roles somehow");

    // Re-create user data
    db.createUser({user: 'user', pwd: 'password', roles: jsTest.basicUserRoles});
    db.createRole({role: 'role', roles: [], privileges: []});
    userCount = 1;
    rolesCount = 1;

    assert.eq(1, db.bar.findOne().a);
    assert.eq(userCount, db.getUsers().length, "didn't create user");
    assert.eq(rolesCount, db.getRoles().length, "didn't create role");

    jsTestLog("Dump foo database *with* user data");
    runTool("mongodump", mongod, {out: dumpDir, db: "foo", dumpDbUsersAndRoles: ""});
    db = mongod.getDB('foo');

    db.dropDatabase();
    db.dropAllUsers();
    db.dropAllRoles();

    assert.eq(0, db.getUsers().length, "didn't drop users");
    assert.eq(0, db.getRoles().length, "didn't drop roles");
    assert.eq(0, db.bar.count(), "didn't drop 'bar' collection");

    jsTestLog("Restore foo database without restoring user data, even though it's in the dump");
    runTool("mongorestore", mongod, {dir: dumpDir + "foo/", db: 'foo', writeConcern: "0"});
    db = mongod.getDB('foo');

    assert.soon(function() {
        return db.bar.findOne();
    }, "no data after restore");
    assert.eq(1, db.bar.findOne().a);
    assert.eq(0, db.getUsers().length, "Restored users even though it shouldn't have");
    assert.eq(0, db.getRoles().length, "Restored roles even though it shouldn't have");

    jsTestLog("Restore foo database *with* user data");
    // SERVER-23290: removed writeConcern: "0" from the mongorestore command line options because,
    // with it, sometimes the following assert.soon would succeed and then then userCount assert
    // would fail because it was not yet available
    runTool("mongorestore", mongod, {dir: dumpDir + "foo/", db: 'foo', restoreDbUsersAndRoles: ""});
    db = mongod.getDB('foo');
    admindb = mongod.getDB('admin');

    assert.soon(function() {
        return db.bar.findOne();
    }, "no data after restore");
    assert.eq(1, db.bar.findOne().a);
    assert.eq(userCount, db.getUsers().length, "didn't restore users");
    assert.eq(rolesCount, db.getRoles().length, "didn't restore roles");
    assert.eq(
        1, admindb.system.users.count({user: "restore", db: "admin"}), "Restore user is missing");
    assert.docEq(versionDoc,
                 db.getSiblingDB('admin').system.version.findOne(),
                 "version doc was changed by restore");

    jsTestLog("Make modifications to user data that should be overridden by the restore");
    db.dropUser('user');
    db.createUser({user: 'user2', pwd: 'password2', roles: jsTest.basicUserRoles});
    db.dropRole('role');
    db.createRole({role: 'role2', roles: [], privileges: []});

    jsTestLog("Restore foo database (and user data) with --drop so it overrides the changes made");
    // Restore with --drop to override the changes to user data
    runTool("mongorestore", mongod, {
        dir: dumpDir + "foo/",
        db: 'foo',
        drop: "",
        restoreDbUsersAndRoles: "",
        writeConcern: "0"
    });
    db = mongod.getDB('foo');
    admindb = mongod.getDB('admin');

    assert.soon(function() {
        return db.bar.findOne();
    }, "no data after restore");
    assert.eq(adminUsersCount, admindb.getUsers().length, "Admin users were dropped");
    assert.eq(adminRolesCount, admindb.getRoles().length, "Admin roles were dropped");
    assert.eq(1, db.bar.findOne().a);
    assert.eq(userCount, db.getUsers().length, "didn't restore users");
    assert.eq("user", db.getUser('user').user, "didn't update user");
    assert.eq(rolesCount, db.getRoles().length, "didn't restore roles");
    assert.eq("role", db.getRole('role').role, "didn't update role");
    assert.docEq(versionDoc,
                 db.getSiblingDB('admin').system.version.findOne(),
                 "version doc was changed by restore");

    jsTestLog("Dump just the admin database.  User data should be dumped by default");
    // Make a user in another database to make sure it is properly captured
    db.getSiblingDB('bar').createUser({user: "user", pwd: 'pwd', roles: []});
    db.getSiblingDB('admin').createUser({user: "user", pwd: 'pwd', roles: []});
    adminUsersCount += 1;
    runTool("mongodump", mongod, {out: dumpDir, db: "admin"});
    db = mongod.getDB('foo');

    // Change user data a bit.
    db.dropAllUsers();
    db.getSiblingDB('bar').createUser({user: "user2", pwd: 'pwd', roles: []});
    db.getSiblingDB('admin').dropAllUsers();

    jsTestLog("Restore just the admin database. User data should be restored by default");
    runTool("mongorestore",
            mongod,
            {dir: dumpDir + "admin/", db: 'admin', drop: "", writeConcern: "0"});
    db = mongod.getDB('foo');
    var otherdb = db.getSiblingDB('bar');
    var admindb = db.getSiblingDB('admin');

    assert.soon(function() {
        return db.bar.findOne();
    }, "no data after restore");
    assert.eq(1, db.bar.findOne().a);
    assert.eq(userCount, db.getUsers().length, "didn't restore users");
    assert.eq("user", db.getUser('user').user, "didn't restore user");
    assert.eq(rolesCount, db.getRoles().length, "didn't restore roles");
    assert.eq("role", db.getRole('role').role, "didn't restore role");
    assert.eq(1, otherdb.getUsers().length, "didn't restore users for bar database");
    assert.eq("user", otherdb.getUsers()[0].user, "didn't restore user for bar database");
    assert.eq(
        adminUsersCount, admindb.getUsers().length, "didn't restore users for admin database");
    assert.eq("user", admindb.getUser("user").user, "didn't restore user for admin database");
    assert.eq(6, admindb.system.users.count(), "has the wrong # of users for the whole server");
    assert.eq(2, admindb.system.roles.count(), "has the wrong # of roles for the whole server");
    assert.docEq(versionDoc,
                 db.getSiblingDB('admin').system.version.findOne(),
                 "version doc was changed by restore");

    jsTestLog("Dump all databases");
    runTool("mongodump", mongod, {out: dumpDir});
    db = mongod.getDB('foo');

    db.dropDatabase();
    db.dropAllUsers();
    db.dropAllRoles();

    assert.eq(0, db.getUsers().length, "didn't drop users");
    assert.eq(0, db.getRoles().length, "didn't drop roles");
    assert.eq(0, db.bar.count(), "didn't drop 'bar' collection");

    jsTestLog("Restore all databases");
    runTool("mongorestore", mongod, {dir: dumpDir, writeConcern: "0"});
    db = mongod.getDB('foo');

    assert.soon(function() {
        return db.bar.findOne();
    }, "no data after restore");
    assert.eq(1, db.bar.findOne().a);
    assert.eq(1, db.getUsers().length, "didn't restore users");
    assert.eq(1, db.getRoles().length, "didn't restore roles");
    assert.docEq(versionDoc,
                 db.getSiblingDB('admin').system.version.findOne(),
                 "version doc was changed by restore");

    MongoRunner.stopMongod(mongod);
};

// Tests that the default auth roles of backup and restore work properly.
dumpRestoreAuth3("backup", "restore");

// Tests that root has backup and restore privileges too.
dumpRestoreAuth3("root", "root");