def validation_result(validated): if bool(validated['invalid']): # if the profile is invalid return [False, decode_to_string(validated['invalid'])] elif bool(validated['custom']): # if the profile has custom permissions message = get_message(validated, 'valid', 'Your user\'s role set ', ' seem to be ok, but we couldn\'t do an exhaustive check.') return [2, message] # if everything seems to be ok return [True, decode_to_string(validated['valid'])]
def validation_result(validated): if bool(validated['invalid']): # if the profile is invalid return [False, decode_to_string(validated['invalid'])] elif bool(validated['custom']): # if the profile has custom permissions message = get_message( validated, 'valid', 'Your user\'s role set ', ' seem to be ok, but we couldn\'t do an exhaustive check.') return [2, message] # if everything seems to be ok return [True, decode_to_string(validated['valid'])]
def try_dedicated_user(test): """ Verify that the role only applies to one database """ roles = test.tester.get_roles() user_role_dbs = set() for role in roles['roles']: user_role_dbs.add(role['db']) return [bool(len(user_role_dbs)), decode_to_string(user_role_dbs)]
def get_message(validated, state, text1, text2): return text1 + decode_to_string(validated[state]) + text2
def try_roles(test): """ Verify that the user roles are not administrative Returns: [bool or 2 , str ]: True Valid role, False invalid role, 2 custome role , """ def valid_role(role): """ Args: role (str): name of a role Returns: Bool: True if the role is not administrative """ return role not in [ 'userAdminAnyDatabase', 'dbAdminAnyDatabase' 'dbAdmin', 'dbOwner', 'userAdmin', 'clusterAdmin' ] def result_default_value(): """ Returns: dict(set()): returns an empty dictionary that contains 3 empty sets where valid, invalid and custom roles are stored """ return {'invalid': set([]), 'valid': set([]), 'custom': set([])} def combine_result(value_1, value_2): """ Args: value_1 (dict(set())): result_default_value value_2 (dict(set())): result_default_value Returns: dict(set()): the union of 2 default values """ return { 'invalid': value_1['invalid'].union(value_2['invalid']), 'valid': value_1['valid'].union(value_2['valid']), 'custom': value_1['custom'].union(value_2['custom']) } def reduce_roles(roles): """ Validate and combine a list of roles Args: roles (list(dict())): roles Returns: result_default_value: roles sorted by valid, invalid, custom """ return reduce(lambda x, y: combine_result(x, y), [validate_role(r) for r in roles]) def basic_validation(roles): """ Basic validation in case validate role fails due to lack of permissions Returns: result_default_value """ validated = result_default_value() for role in roles['roles']: if valid_role(role['role']): validated['valid'].add(role['role']) else: validated['invalid'].add(role['role']) return validated def validate_role(role): """ Recursively process the different roles that a role implements or inherits Args: role (list or dict): value returned by database.command 'usersInfo' or 'rolesInfo' """ if isinstance(role, list) and bool(role): return reduce_roles(role) elif isinstance(role, dict): if 'role' in role and 'isBuiltin' in role: result = result_default_value() is_valid_role = valid_role(role['role']) if is_valid_role and role['isBuiltin']: result['valid'].add(role['role']) elif is_valid_role: result['custom'].add(role['role']) else: result['invalid'].add(role['role']) inherited = validate_role( role['inheritedRoles'] ) if 'inheritedRoles' in role else result_default_value() other_roles = validate_role( role['roles'] ) if 'roles' in role else result_default_value() return combine_result(result, combine_result(inherited, other_roles)) if 'role' in role: return validate_role( database.command('rolesInfo', role)['roles']) if 'roles' in role and bool(role['roles']): return validate_role(role['roles']) else: raise Exception('Non exhaustive type case') elif isinstance(role, list): # empty list return result_default_value() else: raise Exception('Non exhaustive type case') database = test.tester.get_db() roles = test.tester.get_roles() validated = {} def get_message(state, text1, text2): return text1 + decode_to_string(validated[state]) + text2 try: validated = validate_role(roles) except pymongo.errors.OperationFailure: # if the users doesn't have permission to run the command 'rolesInfo' validated = basic_validation(roles) if bool(validated['valid']): message = get_message( 'valid', 'You user permission ', ' didn\'t allow us to do an exhaustive check') return [2, message] # when user has permission to run 'rolesInfo' if bool(validated['invalid']): # if the profile is invalid return [False, decode_to_string(validated['invalid'])] elif bool(validated['custom']): # if the profile has custom permissions message = get_message( 'valid', 'Your user\'s role set ', ' seem to be ok, but we couldn\'t do an exhaustive check.') return [2, message] # if everything seems to be ok return [True, decode_to_string(validated['valid'])]