Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)
Exemplo n.º 3
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&#39;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)
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
    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))
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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))
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    def test_load_from_name_is_case_sensitive(self):
        """
            Test that loading a role by its name is case sensitive.

            Expected result: The method returns the role if the name is the same in the same case, otherwise `None`.
        """

        name = 'Administrator'.upper()
        role = Role(name=name)
        db.session.add(role)
        db.session.commit()

        loaded_role = Role.load_from_name(name)
        self.assertIsNotNone(loaded_role)
        self.assertEqual(name, loaded_role.name)

        loaded_role = Role.load_from_name(name.lower())
        self.assertIsNone(loaded_role)
Exemplo n.º 14
0
    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)
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    def test_role_header_get_no_role(self):
        """
            Test editing a role that does not exist.

            Expected result: An error 404 is returned.
        """

        role = self.create_role(Permission.EditRole)
        self.create_and_login_user(role=role)

        non_existing_role = 'Guest'
        self.assertIsNone(Role.load_from_name(non_existing_role))

        self.get(f'/administration/role/{non_existing_role}',
                 expected_status=404)
Exemplo n.º 17
0
    def test_role_new_post_invalid_name(self):
        """
            Test creating a new role with an invalid name.

            Expected result: The new-role page is shown and no role has been created.
        """

        role = self.create_role(Permission.EditRole)
        self.create_and_login_user(role=role)

        name = Role.invalid_names[0]
        data = self.post('/administration/role/new', data=dict(name=name))

        self.assertIn('Add a New Role', data)
        self.assertNotIn('The new role has been created.', data)
        self.assertIsNone(Role.load_from_name(name))
Exemplo n.º 18
0
    def test_load_from_name_success(self):
        """
            Test loading an existing role via its name.

            Expected result: The role is returned.
        """
        name = 'Administrator'
        role = Role(name=name)
        role_id = 1

        db.session.add(role)
        db.session.commit()

        self.assertEqual(role_id, role.id)

        loaded_role = Role.load_from_name(name)
        self.assertIsNotNone(loaded_role)
        self.assertEqual(role_id, loaded_role.id)
        self.assertEqual(name, loaded_role.name)
Exemplo n.º 19
0
def role_users(name: str) -> str:
    """
        List all users to whom the given role is assigned.

        :param name: The name of the role.
        :return: The HTML response.
    """
    role = Role.load_from_name(name)
    if role is None:
        abort(404)

    # Get a search term and the resulting query. If no search term is given, all users will be returned.
    search_form = SearchForm()
    user_query = User.get_search_query(query=role.users, search_term=search_form.search_term)

    # noinspection PyProtectedMember
    pagination = UserPagination(user_query.order_by(User.name, User._email))

    return render_template('administration/role_users.html', role=name, pagination=pagination, search_form=search_form)
Exemplo n.º 20
0
def role_users(name: str) -> str:
    """
        Show a list of all users to whom the given role is assigned.

        :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)

    # Get a search term and the resulting query. If no search term is given, all users will be returned.
    search_form = SearchForm()
    user_query = User.get_search_query(query=role.users, search_term=search_form.search_term)

    # noinspection PyProtectedMember
    pagination = UserPagination(user_query.order_by(User.name, User._email))

    return render_template('administration/role_users.html', role=name, pagination=pagination, search_form=search_form)
Exemplo n.º 21
0
    def test_load_from_name_success(self):
        """
            Test loading an existing role via its name.

            Expected result: The role is returned.
        """

        name = 'Administrator'
        role = Role(name=name)
        role_id = 1

        db.session.add(role)
        db.session.commit()

        self.assertEqual(role_id, role.id)

        loaded_role = Role.load_from_name(name)
        self.assertIsNotNone(loaded_role)
        self.assertEqual(role_id, loaded_role.id)
        self.assertEqual(name, loaded_role.name)
Exemplo n.º 22
0
def role_edit(name: str) -> str:
    """
        Show a form to edit an existing role.

        :param name: The name of the role to edit.
        :return: The HTML response.
    """
    role = Role.load_from_name(name)
    if role is None:
        abort(404)

    # Create (and possibly process) the header data form.
    header_form = RoleHeaderDataForm(obj=role)
    if header_form.validate_on_submit():
        header_form.populate_obj(role)
        db.session.commit()

        flash(_('The role has been updated.'))
        return redirect(url_for('.role_edit', name=role.name))

    return render_template('administration/role_header.html', role=name, header_form=header_form)
Exemplo n.º 23
0
    def __call__(self, form: Form, field: Field) -> None:
        """
            Execute the validator.

            :param form: The form to which the field belongs.
            :param field: The field to which this validator is assigned.
            :raise ValidationError: In case the validation fails.
        """

        # This validator does not require data. If there is no data everything is fine.
        name = field.data
        if not name:
            return

        # If the field's data has not changed no further check is needed.
        if field.object_data == name:
            return

        # If there already is a role with that name raise an error.
        role = Role.load_from_name(name)
        if role:
            raise ValidationError(self.message)
Exemplo n.º 24
0
def role_edit(name: str) -> ResponseType:
    """
        Show and process a form to edit an existing 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)

    # Create (and possibly process) the header data form.
    header_form = RoleHeaderDataForm(obj=role)
    if header_form.validate_on_submit():
        header_form.populate_obj(role)
        db.session.commit()

        flash(_('The role has been updated.'))
        return redirect(url_for('.role_edit', name=role.name))

    return render_template('administration/role_header.html', role=name, header_form=header_form)
Exemplo n.º 25
0
    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)
Exemplo n.º 26
0
    def test_role_new_post_success(self):
        """
            Test creating a new role.

            Expected result: The list of roles is shown and the new role has been created.
        """

        role = self.create_role(Permission.EditRole, name='Administrator')
        self.create_and_login_user(role=role)

        name = 'Guest'
        permissions = Permission.EditRole | Permission.EditGlobalSettings
        data = self.post('/administration/role/new',
                         data=dict(name=name,
                                   editrole=True,
                                   editglobalsettings=True))

        self.assertIn('Roles', data)
        self.assertNotIn('Add a New Role', data)
        self.assertIn('The new role has been created.', data)

        role = Role.load_from_name(name)
        self.assertIsNotNone(role)
        self.assertEqual(permissions, role.permissions)