Example #1
0
def edit(slug: str):
    try:
        category = queries.get_category(slug=slug)
    except exceptions.DoesNotExist:
        flask.abort(status=404)
    flask_bouncer.ensure(action=flask_bouncer.EDIT, subject=category)
    form = forms.Edit(obj=category)
    if form.validate_on_submit():
        try:
            operations.update_category(
                category=category,
                title=form.title.data,
                description=form.description.data,
            )
        except exceptions.UnableToUpdate:
            flask.flash(message="Unable to update category.", category="error")
            return flask.redirect(location=flask.url_for(
                endpoint="categories.edit", slug=category.slug))
        else:
            flask.flash(message="Category updated.", category="success")
            return flask.redirect(location=flask.url_for(
                endpoint="categories.display", slug=category.slug))
    context = {"title": f"Edit {category.title}", "form": form}
    return flask.render_template(template_name_or_list="categories/edit.html",
                                 **context)
Example #2
0
def edit(slug: str):
    try:
        blog = queries.get_blog(slug=slug)
    except exceptions.DoesNotExist:
        flask.abort(status=404)
    flask_bouncer.ensure(action=flask_bouncer.EDIT, subject=blog)
    form = forms.Edit(obj=blog)
    form.categories.query = category_models.Category.query.all()
    if form.validate_on_submit():
        try:
            operations.update_blog(
                blog=blog,
                title=form.title.data,
                description=form.description.data,
                body=bleach.clean(text=form.body.data,
                                  **constants.BLEACH_KWARGS),
                categories=form.categories.data,
                published=form.published.data,
                comment=form.comment.data,
            )
        except exceptions.UnableToUpdate:
            flask.flash(message="Unable to update blog.", category="error")
            return flask.redirect(
                location=flask.url_for(endpoint="blogs.edit", slug=blog.slug))
        else:
            flask.flash(message="Blog updated.", category="success")
            return flask.redirect(location=flask.url_for(
                endpoint="blogs.display", slug=blog.slug))
    context = {"title": f"Edit {blog.title}", "form": form}
    return flask.render_template(template_name_or_list="blogs/edit.html",
                                 **context)
Example #3
0
 def post(self):
     flask_bouncer.ensure(action=flask_bouncer.CREATE, subject=models.Blog)
     payload = request.get_json(force=True)
     data = self.serializer.load(data=payload)
     data["author"] = flask_login.current_user
     blog = operations.create_blog(**data)
     return self.serializer.dump(obj=blog), http.HTTPStatus.CREATED
Example #4
0
def edit(username: str):
    try:
        account = queries.get_account(username=username)
    except exceptions.DoesNotExist:
        flask.abort(status=404)
    flask_bouncer.ensure(action=flask_bouncer.EDIT, subject=account)
    form = forms.Edit(obj=account)
    if form.validate_on_submit():
        try:
            operations.update_account(
                account=account,
                display=form.display.data,
                about=form.about.data,
            )
        except exceptions.UnableToUpdate:
            flask.flash(message="Unable to edit account.", category="error")
            return flask.redirect(location=flask.url_for(
                endpoint="accounts.edit", username=account.username))
        else:
            flask.flash(
                message="Account updated.",
                category="success",
            )
            return flask.redirect(location=flask.url_for(
                endpoint="accounts.display", username=account.username))
    context = {"title": f"Edit {account.display}", "form": form}
    return flask.render_template(template_name_or_list="accounts/edit.html",
                                 **context)
Example #5
0
 def put(self, id: int):
     account = queries.get_account(id=id)
     flask_bouncer.ensure(action=flask_bouncer.EDIT, subject=account)
     payload = request.get_json(force=True)
     data = self.serializer.load(data=payload)
     operations.update_account(account=account, **data)
     return self.serializer.dump(obj=account), http.HTTPStatus.ACCEPTED
Example #6
0
            def authorize(act_as_user_id):
                try:
                    ensure(impersonation.IMPERSONATE, load_user(act_as_user_id))
                    return True
                except Unauthorized as e:
                    abort(403, title="Impersonation Failed", message="Sorry, your role in the system does not allow you see a student's view.")

                return False    # normally won't reach here
Example #7
0
def display(slug: str):
    try:
        blog = queries.get_blog(slug=slug)
    except exceptions.DoesNotExist:
        flask.abort(status=404)
    flask_bouncer.ensure(action=flask_bouncer.READ, subject=blog)
    context = {"title": blog.title, "blog": blog}
    return flask.render_template(template_name_or_list="blogs/display.html",
                                 **context)
Example #8
0
def edit_post_with_ensure(post_id):

    # Find an article form a db -- faking for testing
    mary = User(name='mary', admin=False)
    article = Article(author_id=mary.id)

    # bounce them out if they do not have access
    ensure(EDIT, article)
    # edit the post
    return "successfully edited post"
    def edit_post(post_id):

        # Find an article form a db -- faking for testing
        jonathan = User(name='jonathan', admin=False, id=1)
        article = Article(author_id=jonathan.id)

        # bounce them out if they do not have access
        ensure(EDIT, article)
        # edit the post
        return "successfully edited post"
Example #10
0
def edit_post_with_ensure(post_id):

    # Find an article form a db -- faking for testing
    mary = User(name='mary', admin=False)
    article = Article(author_id=mary.id)

    # bounce them out if they do not have access
    ensure(EDIT, article)
    # edit the post
    return "successfully edited post"
Example #11
0
def allow(operation, target):
    """
    This duplicates bouncer's can() operation since flask-bouncer doesn't implement it.
    Named allow() to avoid namespace confusion with bouncer.
    """
    try:
        ensure(operation, target)
        return True
    except Unauthorized:
        return False
Example #12
0
def allow(operation, target):
    """
    This duplicates bouncer's can() operation since flask-bouncer doesn't implement it.
    Named allow() to avoid namespace confusion with bouncer.
    """
    try:
        ensure(operation, target)
        return True
    except Unauthorized:
        return False
Example #13
0
def require(operation, target):
    """
    This is basically Flask-Bouncer's ensure except it throws a 403 instead of a 401
    if the permission check fails. A 403 is more accurate since authentication would
    not help and it would prevent the login box from showing up. Named require() to avoid
    confusion with Flask-Bouncer
    :param operation: same as Flask-Bouncer's ensure
    :param target: same as Flask-Bouncer's ensure
    :return:same as Flask-Bouncer's ensure
    """
    try:
        ensure(operation, target)
    except Unauthorized as e:
        raise Forbidden(e.get_description())
Example #14
0
            def authorize(act_as_user_id):
                try:
                    ensure(impersonation.IMPERSONATE,
                           load_user(act_as_user_id))
                    return True
                except Unauthorized as e:
                    abort(
                        403,
                        title="Impersonation Failed",
                        message=
                        "Sorry, your role in the system does not allow you see a student's view."
                    )

                return False  # normally won't reach here
Example #15
0
def require(operation, target):
    """
    This is basically Flask-Bouncer's ensure except it throws a 403 instead of a 401
    if the permission check fails. A 403 is more accurate since authentication would
    not help and it would prevent the login box from showing up. Named require() to avoid
    confusion with Flask-Bouncer
    :param operation: same as Flask-Bouncer's ensure
    :param target: same as Flask-Bouncer's ensure
    :return:same as Flask-Bouncer's ensure
    """
    try:
        ensure(operation, target)
    except Unauthorized as e:
        raise Forbidden(e.get_description())
Example #16
0
 def post(
     self, blog_id: Optional[int] = None, parent_id: Optional[int] = None
 ):
     flask_bouncer.ensure(
         action=flask_bouncer.CREATE, subject=models.Comment
     )
     payload = request.get_json(force=True)
     data = self.serializer.load(data=payload)
     data["author"] = flask_login.current_user
     if blog_id:
         data["blog"] = blog_queries.get_blog(id=blog_id)
     elif parent_id:
         data["parent"] = queries.get_comment(id=parent_id)
     comment = operations.create_comment(**data)
     return self.serializer.dump(obj=comment), http.HTTPStatus.CREATED
Example #17
0
def require(operation, target, title=None, message=None):
    """
    This is basically Flask-Bouncer's ensure except it also takes an optional
    error title and message that'll be passed to the user if the permission
    check failed. Named require() to avoid confusion with Flask-Bouncer
    :param operation: same as Flask-Bouncer's ensure
    :param target: same as Flask-Bouncer's ensure
    :return:same as Flask-Bouncer's ensure
    """
    try:
        ensure(operation, target)
    except Forbidden as e:
        if not title:
            title = "Forbidden"
        if not message:
            message = e.description
        abort(403, title=title, message=message)
Example #18
0
def require(operation, target, title=None, message=None):
    """
    This is basically Flask-Bouncer's ensure except it throws a 403 instead of a 401
    if the permission check fails. A 403 is more accurate since authentication would
    not help and it would prevent the login box from showing up. Named require() to avoid
    confusion with Flask-Bouncer
    :param operation: same as Flask-Bouncer's ensure
    :param target: same as Flask-Bouncer's ensure
    :return:same as Flask-Bouncer's ensure
    """
    try:
        ensure(operation, target)
    except Unauthorized as e:
        if not title:
            title = "Forbidden"
        if not message:
            message = e.description
        abort(403, title=title, message=message)
Example #19
0
 def _verify_permissions(self, user_id, permissions):
     user = User.query.get(user_id)
     with self.app.app_context():
         # can't figure out how to get into logged in app context, so just force a login here
         login_user(user, force=True)
         admin = user.system_role == SystemRole.sys_admin
         for model_name, operations in permissions.items():
             for operation, permission in operations.items():
                 expected = True
                 try:
                     ensure(operation, model_name)
                 except Unauthorized:
                     expected = False
                 expected = expected or admin
                 self.assertEqual(
                     permission['global'], expected,
                     "Expected permission " + operation + " on " + model_name + " to be " + str(expected))
         # undo the forced login earlier
         logout_user()
Example #20
0
def delete(slug: str):
    try:
        blog = queries.get_blog(slug=slug)
    except exceptions.DoesNotExist:
        flask.abort(status=404)
    flask_bouncer.ensure(action=flask_bouncer.DELETE, subject=blog)
    form = forms.Delete()
    if form.validate_on_submit():
        try:
            operations.delete_blog(blog=blog)
        except exceptions.UnableToDelete:
            flask.flash(message="Unable to delete blog.", category="error")
            return flask.redirect(location=flask.url_for(
                endpoint="blogs.display", slug=blog.slug))
        else:
            flask.flash(message="Blog deleted.", category="success")
            return flask.redirect(location=flask.url_for(
                endpoint="main.landing"))
    context = {"title": f"Delete {blog.title}", "form": form}
    return flask.render_template(template_name_or_list="blogs/delete.html",
                                 **context)
Example #21
0
def delete(username: str):
    try:
        account = queries.get_account(username=username)
    except exceptions.DoesNotExist:
        flask.abort(status=404)
    flask_bouncer.ensure(action=flask_bouncer.DELETE, subject=account)
    form = forms.Delete()
    if form.validate_on_submit():
        try:
            operations.delete_account(account=account,
                                      delete_blogs=form.delete_blogs.data)
        except exceptions.UnableToDelete:
            flask.flash(message="Unable to delete account.", category="error")
            return flask.redirect(location=flask.url_for(
                endpoint="accounts.display", username=account.username))
        else:
            flask.flash(message="Account deleted.", category="success")
            if flask_login.current_user == account:
                flask_login.logout_user()
            return flask.redirect(location=flask.url_for(
                endpoint="main.landing"))
    context = {"title": f"Delete {account.display}", "form": form}
    return flask.render_template(template_name_or_list="accounts/delete.html",
                                 **context)
Example #22
0
def get_logged_in_user_permissions():
    user = User.query.get(current_user.id)
    require(READ, user)
    courses = UserCourse.query \
        .filter_by(user_id=current_user.id) \
        .filter(UserCourse.course_role != CourseRole.dropped) \
        .all()

    admin = user.system_role == SystemRole.sys_admin
    permissions = {}
    models = {
        User.__name__: user,
    }
    operations = {
        MANAGE,
        READ,
        EDIT,
        CREATE,
        DELETE
    }
    # global models
    for model_name, model in models.items():
        # create entry if not already exists
        permissions.setdefault(model_name, {})
        # if not model_name in permissions:
        # permissions[model_name] = {}
        # obtain permission values for each operation
        for operation in operations:
            permissions[model_name][operation] = {'global': True}
            try:
                ensure(operation, model)
            except Unauthorized:
                permissions[model_name][operation]['global'] = False
    # course model
    # model_name / operation / courseId OR global
    permissions['Course'] = {CREATE: {'global': allow(CREATE, Course)}}
    mod_operations = {MANAGE, READ, EDIT, DELETE}
    for operation in mod_operations:
        permissions['Course'].setdefault(operation, {})
        permissions['Course'][operation]['global'] = admin
        for course in courses:
            course_uuid = course.course_uuid
            try:
                ensure(operation, Course(id=course.course_id))
                permissions['Course'][operation][course_uuid] = True
                permissions['Course'][operation]['global'] = True
            except Unauthorized:
                permissions['Course'][operation][course_uuid] = False

    # assignment model
    # model_name / operation / courseId OR global
    permissions['Assignment'] = {}
    mod_operations = {MANAGE, READ, EDIT, CREATE, DELETE}
    for operation in mod_operations:
        permissions['Assignment'].setdefault(operation, {})
        permissions['Assignment'][operation]['global'] = admin
        for course in courses:
            course_uuid = course.course_uuid
            try:
                ensure(operation, Assignment(course_id=course.course_id))
                permissions['Assignment'][operation][course_uuid] = True
                permissions['Assignment'][operation]['global'] = True
            except Unauthorized:
                permissions['Assignment'][operation][course_uuid] = False

    return permissions
Example #23
0
def vuln_review(vcdb_id, vuln_id):
    vulnerability_details = _get_vulnerability_details(vcdb_id,
                                                       simplify_id=False)
    view = vulnerability_details.vulnerability_view
    vuln = vulnerability_details.get_or_create_vulnerability()

    proposal_vulnerability_details = _get_vulnerability_details(
        None, vuln_id=vuln_id, simplify_id=False)
    proposal_view = proposal_vulnerability_details.vulnerability_view
    proposal_vuln = proposal_vulnerability_details.get_or_create_vulnerability(
    )

    form_reject = VulnerabilityProposalReject()
    form_approve = VulnerabilityProposalApprove()
    form_assign = VulnerabilityProposalAssign()
    form_unassign = VulnerabilityProposalUnassign()
    form_publish = VulnerabilityProposalPublish()

    if request.method == 'POST':
        if request.form[
                "review_response"] == "assign" and form_assign.validate_on_submit(
                ):
            ensure(ASSIGN, proposal_vuln)
            if proposal_vuln.is_reviewable():
                proposal_vuln.accept_review(g.user)
                db.session.add(proposal_vuln)
                db.session.commit()
                flash("The review was successfully assigned to you.",
                      "success")
                return redirect(request.url)
            else:
                flash_error("This entry is not in a reviewable state.")

        if request.form[
                "review_response"] == "unassign" and form_unassign.validate_on_submit(
                ):
            ensure(ASSIGN, proposal_vuln)
            if proposal_vuln.is_reviewer(g.user):
                proposal_vuln.deny_review()
                db.session.add(proposal_vuln)
                db.session.commit()
                flash("You successfully unassigned yourself from this review.",
                      "success")
                return redirect(request.url)
            else:
                flash_error("This entry is not assigned to you.")

        if request.form[
                "review_response"] == "approve" and form_approve.validate_on_submit(
                ):
            ensure(APPROVE, proposal_vuln)
            proposal_vuln.accept_change()
            db.session.add(proposal_vuln)
            db.session.commit()
            flash(
                "You approved the proposal. Waiting for the entry to be published by an admin.",
                "success")
            return redirect(request.url)

        if request.form[
                "review_response"] == "reject" and form_reject.validate_on_submit(
                ):
            ensure(REJECT, proposal_vuln)
            proposal_vuln.deny_change(g.user,
                                      form_reject.data["review_feedback"])
            db.session.add(proposal_vuln)
            db.session.commit()
            flash("Waiting for the author to address your feedback.",
                  "success")
            return redirect(request.url)

        if request.form[
                "review_response"] == "publish" and form_publish.validate_on_submit(
                ):
            ensure('PUBLISH', proposal_vuln)
            proposal_vuln.publish_change()
            db.session.add(proposal_vuln)
            db.session.commit()
            # This might be the first entry of its kind so no archiving is necessary.
            if vuln.state:
                vuln.archive_entry()
                db.session.add(vuln)
                db.session.commit()
            flash("Entry was successfully published.", "success")
            return redirect(request.url)

    # Published entries can't be reviewed.
    # if view.state == VulnerabilityState.PUBLISHED:
    #    raise RequestRedirect("/" + str(vcdb_id))
    return render_template(
        "vulnerability/review/review.html",
        proposal_vulnerability_details=proposal_vulnerability_details,
        vulnerability_details=vulnerability_details,
        form_assign=form_assign,
        form_unassign=form_unassign,
        form_reject=form_reject,
        form_approve=form_approve,
        form_publish=form_publish)
Example #24
0
def read(id):
    user = User.query.get_or_404(id)
    ensure(READ, user)
    return APIResult(user.export_data())
Example #25
0
def update(id):
    user = User.query.get_or_404(id)
    ensure(UPDATE, user)
    user.import_data(request.method, request.get_json())
    user.save()
    return APIResult({'self_url': user.get_url()})
Example #26
0
def delete(id):
    user = User.query.get_or_404(id)
    ensure(DELETE, user)
    user.remove()
    return APIResult({}, 204)
Example #27
0
 def delete(self, id: int):
     blog = queries.get_blog(id=id)
     flask_bouncer.ensure(action=flask_bouncer.DELETE, subject=blog)
     blog.delete()
     return dict(), http.HTTPStatus.NO_CONTENT
Example #28
0
 def test(self):
     ensure(self.action, self.subject)
Example #29
0
 def delete(self, id: int):
     comment = queries.get_comment(id=id)
     flask_bouncer.ensure(action=flask_bouncer.DELETE, subject=comment)
     comment.delete()
     return dict(), http.HTTPStatus.NO_CONTENT
Example #30
0
def get_logged_in_user_permissions():
    user = Users.query.get(current_user.id)
    require(READ, user)
    dropped_id = UserTypesForCourse.query.filter_by(name=UserTypesForCourse.TYPE_DROPPED).first().id
    courses = CoursesAndUsers.query.filter_by(users_id=current_user.id) \
        .filter(CoursesAndUsers.usertypesforcourse_id != dropped_id).all()
    admin = user.usertypeforsystem.name == "System Administrator"
    permissions = {}
    models = {
        Users.__name__: Users,
    }
    post_based_models = {
        PostsForQuestions.__name__: PostsForQuestions()
    }
    operations = {
        MANAGE,
        READ,
        EDIT,
        CREATE,
        DELETE
    }
    # global models
    for model_name, model in models.items():
        # create entry if not already exists
        permissions.setdefault(model_name, {})
        # if not model_name in permissions:
        # permissions[model_name] = {}
        # obtain permission values for each operation
        for operation in operations:
            permissions[model_name][operation] = {'global': True}
            try:
                ensure(operation, model)
            except Unauthorized:
                permissions[model_name][operation]['global'] = False
    # course model
    # model_name / operation / courseId OR global
    permissions['Courses'] = {CREATE: {'global': allow(CREATE, Courses)}}
    mod_operations = {MANAGE, READ, EDIT, DELETE}
    for operation in mod_operations:
        permissions['Courses'].setdefault(operation, {})
        permissions['Courses'][operation]['global'] = admin
        for course in courses:
            course_id = str(course.courses_id)
            try:
                ensure(operation, Courses(id=course.courses_id))
                permissions['Courses'][operation][course_id] = True
                permissions['Courses'][operation]['global'] = True
            except Unauthorized:
                permissions['Courses'][operation][course_id] = False

    # post-based models
    for model_name, model in post_based_models.items():
        permissions.setdefault(model_name, {})
        for operation in operations:
            permissions[model_name].setdefault(operation, {})
            permissions[model_name][operation]['global'] = admin
            for course in courses:
                course_id = str(course.courses_id)
                try:
                    m = model
                    p = Posts(courses_id=course.courses_id)
                    setattr(m, 'post', p)
                    ensure(operation, m)
                    permissions[model_name][operation][course_id] = True
                    permissions[model_name][operation]['global'] = True
                except Unauthorized:
                    permissions[model_name][operation][course_id] = False

    return permissions
Example #31
0
 def test(self):
     ensure(self.action, self.subject)