1+ // This test is a basic sanity check of the shell helpers for manipulating role objects
2+ // It is not a comprehensive test of the functionality of the role manipulation commands
3+
4+ function assertHasRole ( rolesArray , roleName , roleDB ) {
5+ for ( i in rolesArray ) {
6+ var curRole = rolesArray [ i ] ;
7+ if ( curRole . name == roleName && curRole . db == roleDB ) {
8+ return ;
9+ }
10+ }
11+ assert ( false , "role " + roleName + "@" + roleDB + " not found in array: " + tojson ( rolesArray ) ) ;
12+ }
13+
14+ function assertHasPrivilege ( privilegeArray , privilege ) {
15+ for ( i in privilegeArray ) {
16+ var curPriv = privilegeArray [ i ] ;
17+ if ( curPriv . resource . cluster == privilege . resource . cluster &&
18+ curPriv . resource . anyResource == privilege . resource . anyResource &&
19+ curPriv . resource . db == privilege . resource . db &&
20+ curPriv . resource . collection == privilege . resource . collection ) {
21+ // Same resource
22+ assert . eq ( curPriv . actions . length , privilege . actions . length ) ;
23+ for ( k in curPriv . actions ) {
24+ assert . eq ( curPriv . actions [ k ] , privilege . actions [ k ] ) ;
25+ }
26+ return ;
27+ }
28+ }
29+ assert ( false , "Privilege " + tojson ( privilege ) + " not found in privilege array: " +
30+ tojson ( privilegeArray ) ) ;
31+ }
32+
33+ ( function ( db ) {
34+ var db = db . getSiblingDB ( "role_management_helpers" ) ;
35+ db . dropDatabase ( ) ;
36+ db . dropAllRoles ( ) ;
37+
38+ db . addRole ( { name :'roleA' , roles : [ ] , privileges : [ { resource : { db :db . getName ( ) , collection : "" } ,
39+ actions : [ 'find' ] } ] } ) ;
40+ db . addRole ( { name :'roleB' , privileges : [ ] , roles : [ "roleA" ] } ) ;
41+ db . addRole ( { name :'roleC' , privileges : [ ] , roles : [ ] } ) ;
42+
43+ // Test getRole
44+ var roleObj = db . getRole ( "roleA" ) ;
45+ assert . eq ( 0 , roleObj . roles . length ) ;
46+ assert . eq ( 1 , roleObj . privileges . length ) ;
47+ assertHasPrivilege ( roleObj . privileges ,
48+ { resource : { db :db . getName ( ) , collection :"" } , actions :[ 'find' ] } ) ;
49+ roleObj = db . getRole ( "roleB" ) ;
50+ assert . eq ( 1 , roleObj . privileges . length ) ; // inherited from roleA
51+ assertHasPrivilege ( roleObj . privileges ,
52+ { resource : { db :db . getName ( ) , collection :"" } , actions :[ 'find' ] } ) ;
53+ assert . eq ( 1 , roleObj . roles . length ) ;
54+ assertHasRole ( roleObj . roles , "roleA" , db . getName ( ) ) ;
55+
56+ // Granting roles to nonexistent role fails
57+ assert . throws ( function ( ) { db . grantRolesToRole ( "fakeRole" , [ 'dbAdmin' ] ) ; } ) ;
58+ // Granting roles to built-in role fails
59+ assert . throws ( function ( ) { db . grantRolesToRole ( "readWrite" , [ 'dbAdmin' ] ) ; } ) ;
60+ // Granting non-existant role fails
61+ assert . throws ( function ( ) { db . grantRolesToRole ( "roleB" , [ 'dbAdmin' , 'fakeRole' ] ) ; } ) ;
62+
63+ roleObj = db . getRole ( "roleB" ) ;
64+ assert . eq ( 1 , roleObj . privileges . length ) ;
65+ assert . eq ( 1 , roleObj . roles . length ) ;
66+ assertHasRole ( roleObj . roles , "roleA" , db . getName ( ) ) ;
67+
68+ // Granting a role you already have is no problem
69+ db . grantRolesToRole ( "roleB" , [ 'readWrite' , 'roleC' ] ) ;
70+ roleObj = db . getRole ( "roleB" ) ;
71+ assert . gt ( roleObj . privileges . length , 1 ) ; // Got privileges from readWrite role
72+ assert . eq ( 3 , roleObj . roles . length ) ;
73+ assertHasRole ( roleObj . roles , "readWrite" , db . getName ( ) ) ;
74+ assertHasRole ( roleObj . roles , "roleA" , db . getName ( ) ) ;
75+ assertHasRole ( roleObj . roles , "roleC" , db . getName ( ) ) ;
76+
77+ // Revoking roles the role doesn't have is fine
78+ db . revokeRolesFromRole ( "roleB" , [ 'roleA' , 'readWrite' , 'dbAdmin' ] ) ;
79+ roleObj = db . getRole ( "roleB" ) ;
80+ assert . eq ( 0 , roleObj . privileges . length ) ;
81+ assert . eq ( 1 , roleObj . roles . length ) ;
82+ assertHasRole ( roleObj . roles , "roleC" , db . getName ( ) ) ;
83+
84+ // Privileges on the same resource get collapsed
85+ db . grantPrivilegesToRole ( "roleA" ,
86+ [ { resource : { cluster :true } , actions :[ 'listDatabases' ] } ,
87+ { resource : { db :db . getName ( ) , collection :"" } , actions :[ 'insert' ] } ] ) ;
88+ roleObj = db . getRole ( "roleA" ) ;
89+ assert . eq ( 0 , roleObj . roles . length ) ;
90+ assert . eq ( 2 , roleObj . privileges . length ) ;
91+ assertHasPrivilege ( roleObj . privileges ,
92+ { resource : { db :db . getName ( ) , collection :"" } , actions :[ 'find' , 'insert' ] } ) ;
93+ assertHasPrivilege ( roleObj . privileges ,
94+ { resource : { cluster :true } , actions :[ 'listDatabases' ] } ) ;
95+
96+
97+ // Test dropRole
98+ db . dropRole ( 'roleC' ) ;
99+ assert . throws ( function ( ) { db . getRole ( 'roleC' ) } ) ;
100+ roleObj = db . getRole ( "roleB" ) ;
101+ assert . eq ( 0 , roleObj . privileges . length ) ;
102+ assert . eq ( 0 , roleObj . roles . length ) ;
103+
104+ // Test dropAllRoles
105+ db . dropAllRoles ( ) ;
106+ assert . throws ( function ( ) { db . getRole ( 'roleA' ) } ) ;
107+ assert . throws ( function ( ) { db . getRole ( 'roleB' ) } ) ;
108+ assert . throws ( function ( ) { db . getRole ( 'roleC' ) } ) ;
109+
110+ } ( db ) ) ;
0 commit comments