summaryrefslogtreecommitdiff
path: root/jstests/auth/builtin_roles.js
blob: f99fca2061bdb5906df7cf7b600fe6b218c668ff (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
// Check that builtin roles contain valid permissions.

(function() {
'use strict';

function assertIsBuiltinRole(def, name, expectPrivs = false, expectAuthRest = false) {
    jsTest.log(tojson(def));
    assert.eq(def.db, name.db);
    assert.eq(def.role, name.role);
    assert.eq(def.isBuiltin, true);
    assert.eq(def.roles.length, 0);
    assert.eq(def.inheritedRoles.length, 0);
    if (expectPrivs === false) {
        assert(def.privileges === undefined);
        assert(def.inheritedPrivileges === undefined);
    } else if (expectPrivs === true) {
        assert.gt(def.privileges.length, 0);
        assert.eq(bsonWoCompare(def.privileges, def.inheritedPrivileges), 0);
    } else {
        assert.eq(bsonWoCompare(def.privileges, expectPrivs), 0);
        assert.eq(bsonWoCompare(def.privileges, def.inheritedPrivileges), 0);
    }
    if (expectAuthRest === false) {
        assert(def.authenticationRestrictions === undefined);
        assert(def.inheritedAuthenticationRestrictions === undefined);
    } else if (expectAuthRest === true) {
        assert.eq(def.authenticationRestrictions.length, 0);
        assert.eq(def.inheritedAuthenticationRestrictions.length, 0);
    } else {
        // Builtin roles never have authentication restrictions.
        assert(false);
    }
}

function runTest(mongo) {
    const admin = mongo.getDB('admin');
    const test = mongo.getDB('test');

    function rolesInfo(db, role, basic = false) {
        const cmd = {
            rolesInfo: role,
            showPrivileges: !basic,
            showAuthenticationRestrictions: !basic,
            showBuiltinRoles: !basic,
        };
        return assert.commandWorked(db.runCommand(cmd))
            .roles.sort((a, b) => (a.role + '.' + a.db).localeCompare(b.role + '.' + b.db, 'en'));
    }

    const kTestReadRole = {role: 'read', db: 'test'};
    const kAdminReadRole = {role: 'read', db: 'admin'};
    const kReadRoleActions = [
        'changeStream',
        'collStats',
        'dbHash',
        'dbStats',
        'find',
        'killCursors',
        'listCollections',
        'listIndexes',
        'planCacheRead'
    ];
    const kAdminReadPrivs = [
        {resource: {db: 'admin', collection: ''}, actions: kReadRoleActions},
        {resource: {db: 'admin', collection: 'system.js'}, actions: kReadRoleActions},
    ];
    const kTestReadPrivs = [
        {resource: {db: 'test', collection: ''}, actions: kReadRoleActions},
        {resource: {db: 'test', collection: 'system.js'}, actions: kReadRoleActions},
    ];

    const adminReadBasic = rolesInfo(admin, 'read', true);
    assert.eq(adminReadBasic.length, 1);
    assertIsBuiltinRole(adminReadBasic[0], kAdminReadRole, false, false);

    const adminRead = rolesInfo(admin, 'read');
    assert.eq(adminRead.length, 1);
    assertIsBuiltinRole(adminRead[0], kAdminReadRole, true, true);
    assertIsBuiltinRole(adminRead[0], kAdminReadRole, kAdminReadPrivs, true);

    const testRead = rolesInfo(admin, kTestReadRole);
    assert.eq(testRead.length, 1);
    assertIsBuiltinRole(testRead[0], kTestReadRole, true, true);
    assertIsBuiltinRole(testRead[0], kTestReadRole, kTestReadPrivs, true);

    const testMulti = rolesInfo(admin, ['read', kTestReadRole]);
    assert.eq(testMulti.length, 2);
    assertIsBuiltinRole(testMulti[0], kAdminReadRole, kAdminReadPrivs, true);
    assertIsBuiltinRole(testMulti[1], kTestReadRole, kTestReadPrivs, true);

    const testRole1Privs = [{resource: {db: 'test', collection: ''}, actions: ['insert']}];
    assert.commandWorked(
        test.runCommand({createRole: 'role1', roles: ['read'], privileges: testRole1Privs}));

    const testRoles = rolesInfo(test, 1);
    const testUserRoles = testRoles.filter((r) => !r.isBuiltin);
    assert.eq(testUserRoles.length, 1);
    const testUserRole1 = testUserRoles[0];
    jsTest.log('testUserRole1: ' + tojson(testUserRole1));
    assert.eq(testUserRole1.db, 'test');
    assert.eq(testUserRole1.role, 'role1');
    assert.eq(testUserRole1.roles, [kTestReadRole]);
    assert.eq(testUserRole1.inheritedRoles, [kTestReadRole]);
    assert.eq(testUserRole1.privileges, testRole1Privs);
    assert.eq(testUserRole1.inheritedPrivileges, testRole1Privs.concat(kTestReadPrivs));

    const testRolesReadRole = testRoles.filter((r) => r.role === 'read');
    assert.eq(testRolesReadRole.length, 1);
    assertIsBuiltinRole(testRolesReadRole[0], kTestReadRole, kTestReadPrivs, true);
}

// Standalone
const mongod = MongoRunner.runMongod();
runTest(mongod);
MongoRunner.stopMongod(mongod);

const st = new ShardingTest({shards: 1, mongos: 1, config: 1, other: {shardAsReplicaSet: false}});
runTest(st.s0);
st.stop();
})();