def test_has_permissions_one_of_single_permission(self): """ Test the has_permissions_one_of() method if a role has the request permission (and only this one). Expected result: `True` when requesting this permission, `False` otherwise. """ role = Role('Administrator') role.permissions = Permission.EditRole self.assertTrue(role.has_permissions_one_of(Permission.EditRole)) self.assertFalse(role.has_permissions_one_of(Permission.EditUser)) # If a combination of multiple permissions is requested, the role does not have this permission. self.assertFalse( role.has_permissions_one_of(Permission.EditRole | Permission.EditUser)) role.permissions = Permission.EditUser self.assertFalse(role.has_permissions_one_of(Permission.EditRole)) self.assertTrue(role.has_permissions_one_of(Permission.EditUser)) # If a combination of multiple permissions is requested, the role does not have this permission. self.assertFalse( role.has_permissions_one_of(Permission.EditRole | Permission.EditUser))
def test_init_has_users(self): """ Test that the form is correctly initialized if the role has users. Expected result: The new_role field exists and is initialized with all other roles. """ role = Role(name='Administrator') user = User('*****@*****.**', 'Jane Doe') user.role = role other_role_1 = Role(name='Visitor') other_role_2 = Role(name='Guest') db.session.add(role) db.session.add(user) db.session.add(other_role_1) db.session.add(other_role_2) db.session.commit() # The role choices are ordered by name and skip the role to delete. choices = [ (0, ''), (other_role_2.id, other_role_2.name), (other_role_1.id, other_role_1.name), ] self.assertLess(other_role_1.id, other_role_2.id) self.assertListEqual([user], role.users.all()) form = RoleDeleteForm(role) self.assertIsNotNone(form.new_role) self.assertListEqual(choices, form.new_role.choices)
def test_delete_has_users_new_role(self): """ Test deleting a role if there are still users and a valid new role is given. Expected result: The role is deleted. The role is assigned to all users who had the old role (but not to others). """ # The role that will be deleted. name = 'Administrator' role = Role(name=name) user = User('*****@*****.**', 'Jane Doe') user.role = role db.session.add(role) db.session.add(user) # The new role for the user. new_role = Role(name='Guest') db.session.add(new_role) # Another role and user who will stay untouched. other_role = Role(name='User') other_user = User('*****@*****.**', 'John Doe') other_user.role = other_role db.session.add(other_role) db.session.add(other_user) db.session.commit() role.delete(new_role) loaded_role = Role.load_from_name(name) self.assertIsNone(loaded_role) self.assertEqual(new_role, user.role) self.assertEqual(other_role, other_user.role)
def test_get_search_query_no_term(self): """ Test getting a search query without providing a search term. :return: A query is returned that does not filter. """ role_1 = Role(name='Administrator') role_2 = Role(name='Guest') role_3 = Role(name='User') role_4 = Role(name='Author') db.session.add(role_1) db.session.add(role_2) db.session.add(role_3) db.session.add(role_4) db.session.commit() result = [ role_1, role_2, role_3, role_4, ] query = Role.get_search_query() self.assertIsNotNone(query) roles = query.all() self.assertListEqual(result, roles)
def test_load_roles_with_permission(self): """ Test loading roles that have a given permission. Expected result: All roles that have the requested permission are returned. """ requested_permission = Permission.EditRole other_permission = Permission.EditUser role_without_permission = Role(name='No Permission') role_without_permission.permissions = other_permission db.session.add(role_without_permission) role_with_permission = Role(name='With Permission') role_with_permission.permissions = requested_permission db.session.add(role_with_permission) role_with_permissions = Role(name='With Permissions') role_with_permissions.permissions = requested_permission | other_permission db.session.add(role_with_permissions) db.session.commit() roles = Role.load_roles_with_permission(requested_permission) self.assertListEqual([role_with_permission, role_with_permissions], roles)
def test_get_search_query_with_base_query_and_term(self): """ Test getting a search query providing a base query and a search term. :return: A query is returned that filters exactly by the search term. """ role_1 = Role(name='Administrator') role_2 = Role(name='Guest') role_3 = Role(name='User') role_4 = Role(name='Author') db.session.add(role_1) db.session.add(role_2) db.session.add(role_3) db.session.add(role_4) db.session.commit() base_query = Role.query.order_by(Role._name.desc()) # Matching term. query = Role.get_search_query(query=base_query, search_term='A*') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_4, role_1], roles) # Test that a different result is returned without the given base query. query = Role.get_search_query(search_term='A*') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1, role_4], roles)
def test_get_search_query_with_term_no_wildcards(self): """ Test getting a search query providing a search term without wildcards. :return: A query is returned that filters exactly by the search term. """ role_1 = Role(name='Administrator') role_2 = Role(name='Guest') role_3 = Role(name='User') role_4 = Role(name='Author') db.session.add(role_1) db.session.add(role_2) db.session.add(role_3) db.session.add(role_4) db.session.commit() # Matching term. query = Role.get_search_query(search_term='Administrator') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1], roles) # Not-matching term. query = Role.get_search_query(search_term='Editor') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([], roles) # Partially matching term, but no wildcards, thus no result. query = Role.get_search_query(search_term='A') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([], roles)
def role_delete(name: str) -> str: """ Show a form to delete the given role and process that form. :param name: The name of the role. :return: The HTML response. """ role = Role.load_from_name(name) if role is None: abort(404) # If this is the last role allowed to edit roles show an info text. if role.is_only_role_allowed_to_edit_roles(): deletion_not_possible_text = _('This role cannot be deleted because it is the only one that can edit roles.') return render_template('administration/role_delete.html', role=name, deletion_not_possible_text=deletion_not_possible_text) # Create (and possibly process) the delete form. delete_form = RoleDeleteForm(role) if delete_form.validate_on_submit(): try: new_role_id = delete_form.new_role.data new_role = Role.load_from_id(new_role_id) except AttributeError: # The new_role field might not exist because there are no users. new_role = None role.delete(new_role) flash(_('The role has been deleted.')) return redirect(url_for('.roles_list')) return render_template('administration/role_delete.html', role=name, delete_form=delete_form)
def test_delete_same_role(self): """ Test deleting a role if the same role is given. Expected result: An error is raised. """ name = 'Administrator' role = Role(name=name) user = User('*****@*****.**', 'Jane Doe') user.role = role db.session.add(role) db.session.add(user) db.session.commit() with self.assertRaises(ValueError) as exception_cm: role.delete(role) loaded_role = Role.load_from_name(name) self.assertEqual( 'The new role must not be the role that will be deleted.', str(exception_cm.exception)) self.assertIsNotNone(loaded_role) self.assertEqual(loaded_role, user.role)
def role_delete(name: str) -> ResponseType: """ Show and process a form to delete the given role. :param name: The name of the role. :return: The response for this view. """ role = Role.load_from_name(name) if role is None: abort(404) # If this is the last role allowed to edit roles show an info text. if role.is_only_role_allowed_to_edit_roles(): deletion_not_possible_text = _('This role cannot be deleted because it is the only one that can edit roles.') return render_template('administration/role_delete.html', role=name, deletion_not_possible_text=deletion_not_possible_text) # Create (and possibly process) the delete form. delete_form = RoleDeleteForm(role) if delete_form.validate_on_submit(): try: new_role_id = delete_form.new_role.data new_role = Role.load_from_id(new_role_id) except AttributeError: # The new_role field might not exist because there are no users. new_role = None role.delete(new_role) flash(_('The role has been deleted.')) return redirect(url_for('.roles_list')) return render_template('administration/role_delete.html', role=name, delete_form=delete_form)
def test_permissions_get_less_than_zero(self): """ Test getting the permission enum member if the permission integer is < 0. Expected result: The empty permission. """ role = Role('Administrator') role._permissions = -1 self.assertEqual(Permission(0), role.permissions)
def test_delete_only_role_to_edit_roles(self): """ Test deleting a role that is the only one allowed to edit roles. Expected result: An error is raised. """ name = 'Administrator' permission = Permission.EditRole role = Role(name=name) role.permissions = permission db.session.add(role) db.session.commit() with self.assertRaises(DeletionPreconditionViolationError) as exception_cm: role.delete() self.assertIn('Cannot delete the only role with the permission to edit roles.', str(exception_cm.exception)) # Add another role with the required permission. Now, it is possible to delete the first role. other_role = Role(name='Guest') other_role.permissions = permission db.session.add(other_role) db.session.commit() role.delete() self.assertIsNone(Role.load_from_name(name))
def test_is_only_role_allowed_to_edit_roles(self): """ Test if a role is the only one allowed to edit roles. Expected result: `True` if it is, `False` otherwise. """ # First check if the role is not allowed to edit roles. name = 'Administrator' permission = Permission.EditRole role = Role(name=name) db.session.add(role) db.session.commit() self.assertFalse(role.is_only_role_allowed_to_edit_roles()) # Add the permission. Now it should be the only one. role.permissions = permission db.session.commit() self.assertTrue(role.is_only_role_allowed_to_edit_roles()) # Add another role with the required permission. other_role = Role(name='Guest') other_role.permissions = permission db.session.add(other_role) db.session.commit() self.assertFalse(role.is_only_role_allowed_to_edit_roles())
def test_permissions_get_combination_exists(self): """ Test getting the permission enum member if the permission integer is a combination of two existing enum members. Expected result: The corresponding enum member is returned. """ role = Role('Administrator') role._permissions = (Permission.EditRole | Permission.EditUser).value self.assertEqual(Permission.EditRole | Permission.EditUser, role.permissions)
def test_permissions_get_less_than_zero(self): """ Test getting the permission enum member if the permission integer is < 0. Expected result: The empty permission. """ role = Role('Administrator') role._permissions = -1 self.assertEqual(Permission(0), role.permissions)
def test_has_permissions_one_of_multiple_permissions(self): """ Test the has_permissions_one_of() method if a role has the requested permission (and others). Expected result: `True` when requesting the set permissions. """ role = Role('Administrator') role._permissions = (Permission.EditRole | Permission.EditUser).value self.assertTrue(role.has_permissions_one_of(Permission.EditRole)) self.assertTrue(role.has_permissions_one_of(Permission.EditUser)) self.assertTrue(role.has_permissions_one_of(Permission.EditRole, Permission.EditUser, Permission(0)))
def test_permissions_set_none(self): """ Test setting permissions without giving a permission. Expected result: The empty permission is set. """ role = Role('Administrator') role._permissions = Permission.EditRole.value self.assertEqual(Permission.EditRole, role.permissions) role.permissions = None self.assertEqual(Permission(0).value, role._permissions)
def test_permissions_set_permission(self): """ Test setting permissions with giving a permission. Expected result: The permission is set, overwriting previous values. """ role = Role('Administrator') role._permissions = Permission.EditRole.value self.assertEqual(Permission.EditRole, role.permissions) role.permissions = Permission.EditUser self.assertEqual(Permission.EditUser.value, role._permissions)
def test_permissions_get_combination_exists(self): """ Test getting the permission enum member if the permission integer is a combination of two existing enum members. Expected result: The corresponding enum member is returned. """ role = Role('Administrator') role._permissions = (Permission.EditRole | Permission.EditUser).value self.assertEqual(Permission.EditRole | Permission.EditUser, role.permissions)
def test_permissions_set_none(self): """ Test setting permissions without giving a permission. Expected result: The empty permission is set. """ role = Role('Administrator') role._permissions = Permission.EditRole.value self.assertEqual(Permission.EditRole, role.permissions) role.permissions = None self.assertEqual(Permission(0).value, role._permissions)
def test_permissions_set_permission(self): """ Test setting permissions with giving a permission. Expected result: The permission is set, overwriting previous values. """ role = Role('Administrator') role._permissions = Permission.EditRole.value self.assertEqual(Permission.EditRole, role.permissions) role.permissions = Permission.EditUser self.assertEqual(Permission.EditUser.value, role._permissions)
def test_has_permissions_one_of_no_permissions(self): """ Test the has_permissions_one_of() method if a role does not have any permissions. Expected result: `False`. """ role = Role('Administrator') db.session.add(role) db.session.commit() self.assertEqual(0, role._permissions) self.assertFalse(role.has_permissions_one_of(Permission.EditRole)) self.assertFalse(role.has_permissions_one_of(Permission.EditUser))
def test_permissions_get_power_of_two_exist(self): """ Test getting the permission enum member if the permission integer is a power of two and the enum member exists. Expected result: The corresponding enum member is returned. """ role = Role('Administrator') role._permissions = Permission.EditRole.value self.assertEqual(Permission.EditRole, role.permissions) role._permissions = Permission.EditUser.value self.assertEqual(Permission.EditUser, role.permissions)
def test_delete_no_users_no_role(self): """ Test deleting a role if there are no users and no role is given. Expected result: The role is deleted. """ name = 'Administrator' role = Role(name=name) db.session.add(role) db.session.commit() role.delete() loaded_role = Role.load_from_name(name) self.assertIsNone(loaded_role)
def test_permissions_get_combination_not_exists(self): """ Test getting the permission enum member if the permission integer is not a power of two and the enum member does not exist. Expected result: The corresponding enum member is returned. """ role = Role('Administrator') # Choose a value that is high enough to be very unlikely to exist as a permission. role._permissions = (2 ** 64) + (2 ** 63) with self.assertRaises(ValueError): permission = role.permissions self.assertIsNone(permission)
def test_delete_no_users_no_role(self): """ Test deleting a role if there are no users and no role is given. Expected result: The role is deleted. """ name = 'Administrator' role = Role(name=name) db.session.add(role) db.session.commit() role.delete() loaded_role = Role.load_from_name(name) self.assertIsNone(loaded_role)
def test_name_set_invalid(self): """ Try setting an invalid name. Expected result: An error is raised. """ role = Role('Administrator') with self.assertRaises(ValueError) as exception_cm: role.name = role.invalid_names[0] self.assertIsNone(role.name) error = str(exception_cm.exception) self.assertIn('The name may not be one of', error) for name in role.invalid_names: self.assertIn(name, error)
def test_permissions_get_combination_not_exists(self): """ Test getting the permission enum member if the permission integer is not a power of two and the enum member does not exist. Expected result: The corresponding enum member is returned. """ role = Role('Administrator') # Choose a value that is high enough to be very unlikely to exist as a permission. role._permissions = (2**64) + (2**63) with self.assertRaises(ValueError): permission = role.permissions self.assertIsNone(permission)
def test_has_permissions_one_of_no_permissions(self): """ Test the has_permissions_one_of() method if a role does not have any permissions. Expected result: `False`. """ role = Role('Administrator') db.session.add(role) db.session.commit() self.assertEqual(0, role._permissions) self.assertFalse(role.has_permissions_one_of(Permission.EditRole)) self.assertFalse(role.has_permissions_one_of(Permission.EditUser))
def test_permissions_get_power_of_two_exist(self): """ Test getting the permission enum member if the permission integer is a power of two and the enum member exists. Expected result: The corresponding enum member is returned. """ role = Role('Administrator') role._permissions = Permission.EditRole.value self.assertEqual(Permission.EditRole, role.permissions) role._permissions = Permission.EditUser.value self.assertEqual(Permission.EditUser, role.permissions)
def test_has_permissions_one_of_multiple_permissions(self): """ Test the has_permissions_one_of() method if a role has the requested permission (and others). Expected result: `True` when requesting the set permissions. """ role = Role('Administrator') role.permissions = Permission.EditRole | Permission.EditUser self.assertTrue(role.has_permissions_one_of(Permission.EditRole)) self.assertTrue(role.has_permissions_one_of(Permission.EditUser)) self.assertTrue( role.has_permissions_one_of(Permission.EditRole, Permission.EditUser, Permission(0)))
def test_name_set_valid(self): """ Try setting a valid name. Expected result: The name is set. """ old_name = 'Guest' new_name = 'Administrator' role = Role(old_name) self.assertNotIn(new_name, role.invalid_names) self.assertEqual(old_name, role.name) role.name = new_name self.assertEqual(new_name, role._name)
def test_has_permissions_one_of_empty_permission(self): """ Test the has_permissions_one_of() method with the empty permission. Expected result: `False`. """ role = Role('Administrator') db.session.add(role) db.session.commit() self.assertEqual(0, role._permissions) self.assertFalse(role.has_permissions_one_of(Permission(0))) role._permissions = Permission.EditRole.value self.assertFalse(role.has_permissions_one_of(Permission(0)))
def test_role_permissions_post_only_role_to_edit_roles(self): """ Test updating the permissions of a role that is the only role allowed to edit roles. Unset the permission to edit roles. Expected result: The new permissions are set on the role, but the role keeps the permission to edit roles. """ role = self.create_role(Permission.EditRole) self.create_and_login_user(role=role) self.assertTrue(role.is_only_role_allowed_to_edit_roles()) new_permissions = Permission.EditRole | Permission.EditGlobalSettings data = self.post(f'/administration/role/{role.name}/permissions', data=dict( editglobalsettings=True, editrole=False, edituser=None, )) role = Role.load_from_name(role.name) self.assertEqual(new_permissions, role.permissions) self.assertIn('<h1>Edit Role “', data) self.assertIn( 'Define the permissions which the users to whom this role is assigned will have.', data) # The apostrophe is escaped... self.assertIn('The role's permissions have been updated.', data) self.assertNotIn('View the users who have this role assigned to them', data) self.assertNotIn('Permanently delete this role', data) self.assertNotIn('Edit the role\'s header data', data)
def test_role_delete_get(self): """ Test accessing the delete page. Expected result: The role delete form. """ other_role = self.create_role(Permission.EditRole, name='Administrator') role = self.create_role(name='Guest') self.create_and_login_user(role=other_role) role_id = role.id self.assertListEqual([], role.users.all()) data = self.get(f'/administration/role/{role.name}/delete') role = Role.load_from_id(role_id) self.assertIsNotNone(role) self.assertIsNotNone(other_role.id) self.assertIn('<h1>Edit Role “', data) self.assertNotIn('View the users who have this role assigned to them', data) self.assertNotIn('Edit the role\'s header data', data) self.assertNotIn( 'Define the permissions which the users to whom this role is assigned will have.', data) self.assertIn('Permanently delete this role', data) self.assertNotIn('The role has been deleted.', data)
def test_has_permissions_one_of_empty_permission(self): """ Test the has_permissions_one_of() method with the empty permission. Expected result: `False`. """ role = Role('Administrator') db.session.add(role) db.session.commit() self.assertEqual(0, role._permissions) self.assertTrue(role.has_permissions_one_of(Permission(0))) role.permissions = Permission.EditRole self.assertTrue(role.has_permissions_one_of(Permission(0)))
def test_permission_required_all_not_all_permissions(self): """ Test the `permission_required_all` decorator if the user does not have all the requested permissions. Expected result: The request is aborted with an error 403. """ email = '*****@*****.**' name = 'Jane Doe' password = '******' user = User(email, name) user.set_password(password) user.role = Role('Administrator') user.role.permissions = Permission.EditRole db.session.add(user) db.session.commit() user.login(email, password) self.assertTrue(user.role.has_permission(Permission.EditRole)) self.assertFalse(user.role.has_permission(Permission.EditUser)) with self.assertRaises(Forbidden): permission_required_all(Permission.EditRole, Permission.EditUser)(self.view_function)()
def test_role_delete_post_only_allowed_to_edit_roles(self): """ Test accessing the delete page if the role is the only one allowed to edit roles. Expected result: The role delete form is not shown. """ role = self.create_role(Permission.EditRole) self.create_and_login_user(role=role) role_id = role.id data = self.post(f'/administration/role/{role.name}/delete', data=dict(new_role=0, )) role = Role.load_from_id(role_id) self.assertIsNotNone(role) self.assertIsNotNone(role.id) self.assertIn('<h1>Edit Role “', data) self.assertIn( 'This role cannot be deleted because it is the only one that can edit roles.', data) self.assertNotIn('View the users who have this role assigned to them', data) self.assertNotIn('Edit the role\'s header data', data) self.assertNotIn( 'Define the permissions which the users to whom this role is assigned will have.', data) self.assertNotIn('Permanently delete this role', data) self.assertNotIn('The role has been deleted.', data)
def test_name_set_unchanged(self): """ Try setting the name that the role already has. Expected result: No error is raised. """ name = 'Administrator' role = Role(name) # Write the role to the DB so that the uniqueness check will find it. db.session.add(role) db.session.commit() role.name = name self.assertEqual(name, role._name)
def test_call_name_of_different_role(self): """ Test the validator on a field with a different role's name. Expected result: An error is raised. """ class UniqueRoleNameForm(FlaskForm): name = StringField('Name') # Create a test user. name = 'Administrator' role = Role(name=name) db.session.add(role) db.session.commit() message = 'Another role already uses this name.' form = UniqueRoleNameForm() form.name.data = name validator = UniqueRoleName() with self.assertRaises(ValidationError) as thrown_message: # noinspection PyNoneFunctionAssignment validation = validator(form, form.name) self.assertIsNone(validation) self.assertEqual(message, thrown_message)
def role_permissions(name: str) -> ResponseType: """ Show and process a form to change a role's permissions. :param name: The name of the role. :return: The response for this view. """ role = Role.load_from_name(name) if role is None: abort(404) disabled_permissions = None if role.is_only_role_allowed_to_edit_roles(): disabled_permissions = Permission.EditRole permission_form = create_permission_form(PermissionForm, role.permissions, disabled_permissions=disabled_permissions) if permission_form.validate_on_submit(): role.permissions = permission_form.permissions db.session.commit() flash(_('The role\'s permissions have been updated.')) return redirect(url_for('.role_permissions', name=role.name)) return render_template('administration/role_permissions.html', role=name, permission_form=permission_form)
def test_permission_required_one_of_has_permission(self): """ Test the `permission_required` decorator if the user has one of the requested permission, but not all. Expected result: The decorated view function is returned. """ email = '*****@*****.**' name = 'Jane Doe' password = '******' user = User(email, name) user.set_password(password) user.role = Role('Administrator') user.role.permissions = Permission.EditRole db.session.add(user) db.session.commit() user.login(email, password) self.assertTrue(user.role.has_permission(Permission.EditRole)) self.assertFalse(user.role.has_permission(Permission.EditUser)) view_function = permission_required_one_of( Permission.EditRole, Permission.EditUser)(self.view_function) response = view_function() self.assertEqual(self.view_function(), response)
def test_name_set_invalid(self): """ Try setting an invalid name. Expected result: An error is raised. """ role = Role('Administrator') with self.assertRaises(ValueError) as exception_cm: role.name = role.invalid_names[0] self.assertIsNone(role.name) error = str(exception_cm.exception) self.assertIn('The name may not be one of', error) for name in role.invalid_names: self.assertIn(name, error)
def test_permissions_set_permission_no_edit_role_only_role(self): """ Test setting permissions with giving permissions that do not include the permission to edit roles if this is the only role allowed to edit roles. Expected result: The permission to edit roles is set automatically. """ role = Role('Administrator') role.permissions = Permission.EditRole db.session.add(role) db.session.commit() self.assertTrue(role.is_only_role_allowed_to_edit_roles()) role.permissions = Permission.EditUser self.assertEqual(Permission.EditUser | Permission.EditRole, role.permissions)
def test_role_delete_post_has_users(self): """ Test deleting a role that has users. Expected result: The role is deleted. """ other_role = self.create_role(Permission.EditRole, name='Administrator') role = self.create_role(name='Guest') self.create_and_login_user(role=other_role) # Add a user for the role to delete. other_user = self.create_user(email='*****@*****.**', name='John Doe', password='******', role=role) role_id = role.id self.assertListEqual([other_user], role.users.all()) data = self.post(f'/administration/role/{role.name}/delete', data=dict(new_role=other_role.id)) role = Role.load_from_id(role_id) self.assertIsNone(role) self.assertIsNotNone(other_role.id) self.assertNotIn('<h1>Edit Role “', data) self.assertIn('The role has been deleted.', data) # noinspection PyUnresolvedReferences self.assertEqual(other_role, other_user.role)
def test_role_header_post_header_data_new_name(self): """ Test editing a role by setting a new name. Expected result: The edit page is shown, the role is updated. """ name = 'Administrator' role = self.create_role(Permission.EditRole, name=name) self.create_and_login_user(role=role) new_name = 'Guest' data = self.post(f'/administration/role/{name}', data=dict(name=new_name)) role = Role.load_from_id(role.id) self.assertIn(f'Edit Role “{new_name}”', data) self.assertIn('The role has been updated.', data) self.assertEqual(new_name, role.name) self.assertIn('Edit the role\'s header data', data) self.assertNotIn('View the users who have this role assigned to them', data) self.assertNotIn('Permanently delete this role', data) self.assertNotIn( 'Define the permissions which the users to whom this role is assigned will have.', data)
def role_permissions(name: str) -> str: """ Show a form to a role's permissions. :param name: The name of the role. :return: The HTML response. """ role = Role.load_from_name(name) if role is None: abort(404) disabled_permissions = None if role.is_only_role_allowed_to_edit_roles(): disabled_permissions = Permission.EditRole permission_form = create_permission_form(PermissionForm, role.permissions, disabled_permissions=disabled_permissions) if permission_form.validate_on_submit(): role.permissions = permission_form.permissions db.session.commit() flash(_('The role\'s permissions have been updated.')) return redirect(url_for('.role_permissions', name=role.name)) return render_template('administration/role_permissions.html', role=name, permission_form=permission_form)
def test_name_set_valid(self): """ Try setting a valid name. Expected result: The name is set. """ old_name = 'Guest' new_name = 'Administrator' role = Role(old_name) self.assertNotIn(new_name, role.invalid_names) self.assertEqual(old_name, role.name) role.name = new_name self.assertEqual(new_name, role._name)
def test_get_search_query_no_term(self): """ Test getting a search query without providing a search term. :return: A query is returned that does not filter. """ role_1 = Role(name='Administrator') role_2 = Role(name='Guest') role_3 = Role(name='User') role_4 = Role(name='Author') db.session.add(role_1) db.session.add(role_2) db.session.add(role_3) db.session.add(role_4) db.session.commit() result = [ role_1, role_2, role_3, role_4, ] query = Role.get_search_query() self.assertIsNotNone(query) roles = query.all() self.assertListEqual(result, roles)
def test_repr(self): """ Test the string representation of the role. Expected result: The representation contains details on the role. """ name = 'Administrator' permissions = Permission.EditRole | Permission.EditUser role = Role(name=name) self.assertEqual(f'<Role [None] "{name}" [Permission.0]>', str(role)) role.permissions = permissions db.session.add(role) db.session.commit() self.assertEqual(f'<Role [1] "{name}" [{permissions}]>', str(role))
def test_load_from_id_failure(self): """ Test the role loader function with a non-existing role. Expected result: No role is returned. """ loaded_role = Role.load_from_id(1) self.assertIsNone(loaded_role)
def test_load_from_name_failure(self): """ Test loading a non-existing role via its name. Expected result: Nothing is returned. """ loaded_role = Role.load_from_name('Administrator') self.assertIsNone(loaded_role)
def test_get_search_query_with_term_no_wildcards(self): """ Test getting a search query providing a search term without wildcards. :return: A query is returned that filters exactly by the search term. """ role_1 = Role(name='Administrator') role_2 = Role(name='Guest') role_3 = Role(name='User') role_4 = Role(name='Author') db.session.add(role_1) db.session.add(role_2) db.session.add(role_3) db.session.add(role_4) db.session.commit() # Matching term. query = Role.get_search_query(search_term='Administrator') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1], roles) # Not-matching term. query = Role.get_search_query(search_term='Editor') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([], roles) # Partially matching term, but no wildcards, thus no result. query = Role.get_search_query(search_term='A') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([], roles)
def test_load_roles_with_permission(self): """ Test loading roles that have a given permission. Expected result: All roles that have the requested permission are returned. """ requested_permission = Permission.EditRole other_permission = Permission.EditUser role_without_permission = Role(name='No Permission') role_without_permission.permissions = other_permission db.session.add(role_without_permission) role_with_permission = Role(name='With Permission') role_with_permission.permissions = requested_permission db.session.add(role_with_permission) role_with_permissions = Role(name='With Permissions') role_with_permissions.permissions = requested_permission | other_permission db.session.add(role_with_permissions) db.session.commit() roles = Role.load_roles_with_permission(requested_permission) self.assertListEqual([role_with_permission, role_with_permissions], roles)
def test_is_only_role_allowed_to_edit_roles(self): """ Test if a role is the only one allowed to edit roles. Expected result: `True` if it is, `False` otherwise. """ # First check if the role is not allowed to edit roles. name = 'Administrator' permission = Permission.EditRole role = Role(name=name) db.session.add(role) db.session.commit() self.assertFalse(role.is_only_role_allowed_to_edit_roles()) # Add the permission. Now it should be the only one. role.permissions = permission db.session.commit() self.assertTrue(role.is_only_role_allowed_to_edit_roles()) # Add another role with the required permission. other_role = Role(name='Guest') other_role.permissions = permission db.session.add(other_role) db.session.commit() self.assertFalse(role.is_only_role_allowed_to_edit_roles())
def test_load_roles_with_permissions(self): """ Test loading roles that have multiple given permissions. Expected result: All roles that have the requested permissions are returned. """ first_requested_permission = Permission.EditRole second_requested_permission = Permission.EditGlobalSettings other_permission = Permission.EditUser role_without_permission = Role(name='No Permission') role_without_permission.permissions = other_permission db.session.add(role_without_permission) role_with_one_permission = Role(name='With One Permission') role_with_one_permission.permissions = first_requested_permission db.session.add(role_with_one_permission) role_with_all_permissions = Role(name='With All Permissions') role_with_all_permissions.permissions = (first_requested_permission | second_requested_permission | other_permission) db.session.add(role_with_all_permissions) db.session.commit() roles = Role.load_roles_with_permissions_all(first_requested_permission, second_requested_permission) self.assertListEqual([role_with_all_permissions], roles)
def role_new() -> str: """ Show a form to create a new role. :return: The HTML response. """ new_role_form = create_permission_form(RoleNewForm, Permission(0)) if new_role_form.validate_on_submit(): role = Role(name=new_role_form.name.data) role.permissions = new_role_form.permissions db.session.add(role) db.session.commit() flash(_('The new role has been created.')) return redirect(url_for('.roles_list')) return render_template('administration/role_new.html', new_role_form=new_role_form)
def test_get_search_query_with_term_wildcards(self): """ Test getting a search query providing a search term without wildcards. :return: A query is returned that filters by the search term allowing for partial matches. """ role_1 = Role(name='Administrator') role_2 = Role(name='Guest') role_3 = Role(name='User') role_4 = Role(name='Author') role_5 = Role(name='Assistant') db.session.add(role_1) db.session.add(role_2) db.session.add(role_3) db.session.add(role_4) db.session.add(role_5) db.session.commit() # Matching term. query = Role.get_search_query(search_term='*Administrator*') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1], roles) # Partially matching term with wildcard at the end. query = Role.get_search_query(search_term='A*') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1, role_4, role_5], roles) # Partially matching term with wildcard at the front. query = Role.get_search_query(search_term='*r') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1, role_3, role_4], roles) # Partially matching term with wildcard in the middle. query = Role.get_search_query(search_term='A*r') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1, role_4], roles) # Partially matching term with wildcard at the front and end, case-insensitive. query = Role.get_search_query(search_term='*u*') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_2, role_3, role_4], roles) # Wildcard term matching everything. query = Role.get_search_query(search_term='*') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([role_1, role_2, role_3, role_4, role_5], roles) # Wildcard term matching nothing. query = Role.get_search_query(search_term='E*') self.assertIsNotNone(query) roles = query.all() self.assertListEqual([], roles)
def test_delete_has_users_no_role(self): """ Test deleting a role if there are still users and no role is given. Expected result: An error is raised. """ name = 'Administrator' role = Role(name=name) user = User('*****@*****.**', 'Jane Doe') user.role = role db.session.add(role) db.session.add(user) db.session.commit() with self.assertRaises(ValueError) as exception_cm: role.delete() loaded_role = Role.load_from_name(name) self.assertIn('A new role must be given', str(exception_cm.exception)) self.assertIsNotNone(loaded_role) self.assertEqual(loaded_role, user.role)
def roles_list() -> str: """ Show a list of all roles. :return: The HTML response. """ # Get a search term and the resulting query. If no search term is given, all roles will by returned. search_form = SearchForm() role_query = Role.get_search_query(search_term=search_form.search_term) # noinspection PyProtectedMember pagination = RolePagination(role_query.order_by(Role._name)) title = _('Roles') return render_template('administration/roles.html', title=title, pagination=pagination, search_form=search_form)