Beispiel #1
0
def reset():
    "Reset the password for a user account and send email."
    if utils.http_GET():
        email = flask.request.args.get("email") or ""
        email = email.lower()
        return flask.render_template("user/reset.html", email=email)

    elif utils.http_POST():
        try:
            user = get_user(email=flask.request.form["email"])
            if user is None:
                raise KeyError
            if user["status"] != constants.ENABLED:
                raise KeyError
        except KeyError:
            pass  # Silent when no user found.
        else:
            with UserSaver(user) as saver:
                saver.set_password()
            send_password_code(user, "password reset")
        # Don't advertise whether user exists or not.
        utils.flash_message(
            "An email has been sent, if a user account with the given email address exists."
        )
        return flask.redirect(flask.url_for("home"))
Beispiel #2
0
def login():
    "Login to a user account."
    if utils.http_GET():
        try:
            flask.session["login_target_url"] = flask.request.args[
                "login_target_url"]
        except KeyError:
            pass
        return flask.render_template("user/login.html")

    elif utils.http_POST():
        try:
            do_login(flask.request.form.get("username"),
                     flask.request.form.get("password"))
        except ValueError:
            return utils.error(
                "Invalid user or password, or account disabled.",
                url=flask.url_for(".login"),
            )
        try:
            url = flask.session.pop("login_target_url")
        except KeyError:
            url = flask.url_for("home")
        return flask.redirect(url)

    # HEAD request gets here: return No_Content
    return "", 204
Beispiel #3
0
def create_proposal(cid):
    "Create a new proposal within the call. Redirect to an existing proposal."
    call = get_call(cid)
    if call is None:
        return utils.error("No such call.", flask.url_for("home"))
    if not anubis.proposal.allow_create(call):
        return utils.error("You may not create a proposal.")

    if utils.http_POST():
        proposal = anubis.proposal.get_call_user_proposal(
            cid, flask.g.current_user["username"]
        )
        if proposal:
            return utils.message(
                "Proposal already exists for the call.",
                flask.url_for("proposal.display", pid=proposal["identifier"]),
            )
        else:
            with anubis.proposal.ProposalSaver(
                call=call, user=flask.g.current_user
            ) as saver:
                pass
            return flask.redirect(
                flask.url_for("proposal.edit", pid=saver.doc["identifier"])
            )
Beispiel #4
0
def grant(cid):
    "Display grant field definitions for delete, and add field."
    call = get_call(cid)
    if not call:
        return utils.error("No such call.", flask.url_for("home"))
    if not allow_edit(call):
        return utils.error("You are not allowed to edit the call.")

    if utils.http_GET():
        repeat_fields = [
            f for f in call.get("grant", []) if f["type"] == constants.REPEAT
        ]
        return flask.render_template(
            "call/grant.html",
            call=call,
            repeat_fields=repeat_fields,
            reviews_count=utils.get_count("reviews", "call", call["identifier"]),
        )

    elif utils.http_POST():
        try:
            with CallSaver(call) as saver:
                saver.add_grant_field(flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".grant", cid=call["identifier"]))
Beispiel #5
0
def transfer(pid):
    "Transfer ownership of he proposal."
    proposal = get_proposal(pid)
    if proposal is None:
        return utils.error("No such proposal.", flask.url_for("home"))
    if not allow_transfer(proposal):
        return utils.error("You are not allowed to transfer ownership of"
                           " this proposal.")

    if utils.http_GET():
        return flask.render_template("proposal/transfer.html",
                                     proposal=proposal)

    elif utils.http_POST():
        try:
            with ProposalSaver(proposal) as saver:
                value = flask.request.form.get("user")
                if value:
                    user = anubis.user.get_user(username=value, email=value)
                    if user:
                        saver.set_user(user)
                    else:
                        raise ValueError("No such user.")
        except ValueError as error:
            return utils.error(error)
        return flask.redirect(
            flask.url_for(".display", pid=proposal["identifier"]))
Beispiel #6
0
def register():
    "Register a new user account."
    if utils.http_GET():
        return flask.render_template("user/register.html",
                                     gdpr=utils.get_site_text("gdpr.md"))

    elif utils.http_POST():
        try:
            with UserSaver() as saver:
                saver.set_username(flask.request.form.get("username"))
                saver.set_email(flask.request.form.get("email"))
                if utils.to_bool(flask.request.form.get("enable")):
                    saver.set_status(constants.ENABLED)
                saver.set_role(constants.USER)
                saver.set_call_creator(False)
                saver.set_password()  # Sets code.
                saver.set_givenname(flask.request.form.get("givenname"))
                saver.set_familyname(flask.request.form.get("familyname"))
                saver.set_gender(flask.request.form.get("gender"))
                saver.set_birthdate(flask.request.form.get("birthdate"))
                saver.set_degree(flask.request.form.get("degree"))
                saver.set_affiliation(
                    flask.request.form.get("affiliation")
                    or flask.request.form.get("affiliation_other"))
                saver.set_postaladdress(
                    flask.request.form.get("postaladdress"))
                saver.set_phone(flask.request.form.get("phone"))
            user = saver.doc
        except ValueError as error:
            return utils.error(error, flask.url_for(".register"))
        # Directly enabled; send code to the user, if so instructed.
        if user["status"] == constants.ENABLED:
            if utils.to_bool(flask.request.form.get("send_email")):
                send_password_code(user, "registered")
                utils.flash_message(
                    "User account created; an email with a link"
                    " to set password has been sent.")
            else:
                utils.flash_message("User account created.")
        # Was set to 'pending'; send email to admins.
        else:
            utils.flash_message("User account created; an email will be sent"
                                " when it has been enabled by the admin.")
            admins = get_users(role=constants.ADMIN, status=constants.ENABLED)
            recipients = [u["email"] for u in admins if u["email"]]
            site = flask.current_app.config["SITE_NAME"]
            title = f"{site} user account pending"
            url = flask.url_for(".display",
                                username=user["username"],
                                _external=True)
            text = f"To enable the user account, go to {url}\n\n" "/The Anubis system"
            utils.send_email(recipients, title, text)
        if flask.g.am_admin:
            return flask.redirect(flask.url_for("user.all"))
        else:
            return flask.redirect(flask.url_for("home"))
Beispiel #7
0
def edit(username):
    "Edit the user. Or delete the user."
    user = get_user(username=username)
    if user is None:
        return utils.error("No such user.", flask.url_for("home"))
    if not allow_edit(user):
        return utils.error("Access to user edit not allowed.")

    if utils.http_GET():
        return flask.render_template("user/edit.html",
                                     user=user,
                                     allow_change_role=allow_change_role(user))

    elif utils.http_POST():
        try:
            with UserSaver(user) as saver:
                if flask.g.am_admin:
                    email = flask.request.form.get("email")
                    saver.set_email(email, require=bool(email))
                if allow_change_role(user):
                    saver.set_role(flask.request.form.get("role"))
                    saver.set_call_creator(
                        utils.to_bool(flask.request.form.get("call_creator")))
                saver.set_givenname(flask.request.form.get("givenname"))
                saver.set_familyname(flask.request.form.get("familyname"))
                saver.set_gender(flask.request.form.get("gender"))
                saver.set_birthdate(flask.request.form.get("birthdate"))
                saver.set_degree(flask.request.form.get("degree"))
                saver.set_affiliation(
                    flask.request.form.get("affiliation")
                    or flask.request.form.get("affiliation_other"))
                saver.set_postaladdress(
                    flask.request.form.get("postaladdress"))
                saver.set_phone(flask.request.form.get("phone"))
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(
            flask.url_for(".display", username=user["username"]))

    elif utils.http_DELETE():
        if not allow_delete(user):
            return utils.error(
                "Cannot delete the user account; admin or not empty.",
                flask.url_for(".display", username=username),
            )
        flask.g.db.delete(user)
        utils.flash_message(f"Deleted user {username}.")
        if flask.g.am_admin:
            return flask.redirect(flask.url_for(".all"))
        else:
            return flask.redirect(flask.url_for("home"))
Beispiel #8
0
def unsubmit(pid):
    "Unsubmit the proposal."
    proposal = get_proposal(pid)
    if proposal is None:
        return utils.error("No such proposal.", flask.url_for("home"))

    if utils.http_POST():
        try:
            with ProposalSaver(proposal) as saver:
                saver.set_unsubmitted()  # Tests whether allowed or not.
        except ValueError as error:
            utils.flash_error(error)
        else:
            utils.flash_warning("Proposal was unsubmitted.")
        return flask.redirect(flask.url_for(".display", pid=pid))
Beispiel #9
0
def unfinalize(iuid):
    "Unfinalize the review for the proposal."
    try:
        review = get_review(iuid)
    except KeyError:
        return utils.error("No such review.", flask.url_for("home"))
    if not allow_unfinalize(review):
        return utils.error("You are not allowed to unfinalize this review.")

    if utils.http_POST():
        try:
            with ReviewSaver(doc=review) as saver:
                saver["finalized"] = None
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".display", iuid=review["_id"]))
Beispiel #10
0
def unfinalize(iuid):
    "Unfinalize the decision."
    try:
        decision = get_decision(iuid)
    except KeyError:
        return utils.error("No such decision.", flask.url_for("home"))
    if not allow_unfinalize(decision):
        return utils.error("You are not allowed to unfinalize this decision.")

    if utils.http_POST():
        try:
            with DecisionSaver(doc=decision) as saver:
                saver["finalized"] = None
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".display", iuid=decision["_id"]))
Beispiel #11
0
def unlock(gid):
    "Unlock the grant dossier to allow edits by the user."
    grant = get_grant(gid)
    if grant is None:
        return utils.error("No such grant.")
    if not allow_lock(grant):
        return utils.error("You are not allowed to unlock this grant dossier.")

    if utils.http_POST():
        try:
            with GrantSaver(doc=grant) as saver:
                saver["locked"] = False
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(
            flask.url_for(".display", gid=grant["identifier"]))
Beispiel #12
0
def edit(cid):
    "Edit the call, or delete it."
    call = get_call(cid)
    if not call:
        return utils.error("No such call.", flask.url_for("home"))
    if not allow_edit(call):
        return utils.error("You are not allowed to edit the call.")

    if utils.http_GET():
        return flask.render_template(
            "call/edit.html",
            call=call,
            allow_identifier_edit=allow_identifier_edit(call),
        )

    elif utils.http_POST():
        try:
            with CallSaver(call) as saver:
                saver.set_identifier(flask.request.form.get("identifier"))
                saver.set_title(flask.request.form.get("title"))
                saver["description"] = flask.request.form.get("description")
                saver["home_description"] = (
                    flask.request.form.get("home_description").strip() or None
                )
                saver["opens"] = utils.normalize_datetime(
                    flask.request.form.get("opens")
                )
                saver["closes"] = utils.normalize_datetime(
                    flask.request.form.get("closes")
                )
                saver["reviews_due"] = utils.normalize_datetime(
                    flask.request.form.get("reviews_due")
                )
                saver.edit_access(flask.request.form)
            call = saver.doc
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".display", cid=call["identifier"]))

    elif utils.http_DELETE():
        if not allow_delete(call):
            return utils.error("You are not allowed to delete the call.")
        utils.delete(call)
        utils.flash_message(f"Deleted call {call['identifier']}:{call['title']}.")
        return flask.redirect(
            flask.url_for("calls.owner", username=flask.g.current_user["username"])
        )
Beispiel #13
0
def create():
    "Create a new call from scratch."
    if not allow_create():
        return utils.error("You are not allowed to create a call.")

    if utils.http_GET():
        return flask.render_template("call/create.html")

    elif utils.http_POST():
        try:
            with CallSaver() as saver:
                saver.set_identifier(flask.request.form.get("identifier"))
                saver.set_title(flask.request.form.get("title"))
            call = saver.doc
        except ValueError as error:
            return utils.error(error)
        return flask.redirect(flask.url_for(".edit", cid=call["identifier"]))
Beispiel #14
0
def archive(iuid):
    "Archive the review for the proposal. Requires 'delete' privilege."
    try:
        review = get_review(iuid)
    except KeyError:
        return utils.error("No such review.", flask.url_for("home"))
    # In a sense similar to deleting, so requires same priviliege.
    if not allow_delete(review):
        return utils.error("You are not allowed to archive this review.")

    if utils.http_POST():
        try:
            with ReviewSaver(doc=review) as saver:
                saver.set_archived()
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".display", iuid=review["_id"]))
Beispiel #15
0
def decision(cid):
    "Display decision field definitions for delete, and add field."
    call = get_call(cid)
    if not call:
        return utils.error("No such call.", flask.url_for("home"))
    if not allow_edit(call):
        return utils.error("You are not allowed to edit the call.")

    if utils.http_GET():
        return flask.render_template("call/decision.html", call=call)

    elif utils.http_POST():
        try:
            with CallSaver(call) as saver:
                saver.add_decision_field(flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".decision", cid=call["identifier"]))
Beispiel #16
0
def clone(cid):
    """Clone the call. Copies:
    - Title
    - Description
    - Access fields
    - Proposal fields
    - Review fields
    - Decision fields
    - Grant fields
    Does not copy:
    - Dates
    - Documents
    - Reviewers
    """
    call = get_call(cid)
    if not call:
        return utils.error("No such call.", flask.url_for("home"))

    if not allow_create():
        return utils.error("You are not allowed to create a call.")

    if utils.http_GET():
        return flask.render_template("call/clone.html", call=call)

    elif utils.http_POST():
        try:
            with CallSaver() as saver:
                saver.set_identifier(flask.request.form.get("identifier"))
                saver.set_title(flask.request.form.get("title"))
                saver.doc["description"] = call["description"]
                saver.doc["access"] = call["access"]
                saver.doc["proposal"] = copy.deepcopy(call["proposal"])
                saver.doc["review"] = copy.deepcopy(call["review"])
                saver.doc["decision"] = copy.deepcopy(call.get("decision", []))
                saver.doc["grant"] = copy.deepcopy(call.get("grant", []))
                # Do not copy dates.
                # Do not copy documents.
                # Do not copy reviewers or chairs.
            new = saver.doc
        except ValueError as error:
            return utils.error(error)
        return flask.redirect(flask.url_for(".edit", cid=new["identifier"]))
Beispiel #17
0
def documents(cid):
    "Display documents for delete, or add document (attachment file)."
    call = get_call(cid)
    if not call:
        return utils.error("No such call.", flask.url_for("home"))
    if not allow_edit(call):
        return utils.error("You are not allowed to edit the call.")

    if utils.http_GET():
        return flask.render_template("call/documents.html", call=call)

    elif utils.http_POST():
        infile = flask.request.files.get("document")
        if infile:
            description = flask.request.form.get("document_description")
            with CallSaver(call) as saver:
                saver.add_document(infile, description)
        else:
            utils.flash_error("No document selected.")
        return flask.redirect(flask.url_for(".display", cid=call["identifier"]))
Beispiel #18
0
def access(gid):
    "Edit the access privileges for the grant record."
    grant = get_grant(gid)
    if grant is None:
        return utils.error("No such grant.")
    if not allow_change_access(grant):
        return utils.error("You are not allowed to change access"
                           " for this grant dossier.")
    call = anubis.call.get_call(grant["call"])

    if utils.http_GET():
        users = {}
        for user in grant.get("access_view", []):
            users[user] = False
        for user in grant.get("access_edit", []):
            users[user] = True
        return flask.render_template(
            "access.html",
            title=f"Grant {grant['identifier']}",
            url=flask.url_for(".access", gid=grant["identifier"]),
            users=users,
            back_url=flask.url_for(".display", gid=grant["identifier"]),
        )

    elif utils.http_POST():
        try:
            with GrantSaver(doc=grant) as saver:
                saver.set_access(form=flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".access",
                                            gid=grant["identifier"]))

    elif utils.http_DELETE():
        try:
            with GrantSaver(doc=grant) as saver:
                saver.remove_access(form=flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".access",
                                            gid=grant["identifier"]))
Beispiel #19
0
def edit(gid):
    "Edit the grant dossier."
    grant = get_grant(gid)
    if grant is None:
        return utils.error("No such grant.")
    call = anubis.call.get_call(grant["call"])

    if utils.http_GET():
        if not allow_edit(grant):
            return utils.error(
                "You are not allowed to edit this grant dossier.")
        return flask.render_template("grant/edit.html", grant=grant, call=call)

    elif utils.http_POST():
        if not allow_edit(grant):
            return utils.error(
                "You are not allowed to edit this grant dossier.")
        try:
            with GrantSaver(doc=grant) as saver:
                saver.set_fields_values(call.get("grant", []),
                                        form=flask.request.form)
        except ValueError as error:
            return utils.error(error)
        if saver.repeat_changed:
            url = flask.url_for(".edit", gid=grant["identifier"])
        else:
            url = flask.url_for(".display", gid=grant["identifier"])
        return flask.redirect(url)

    elif utils.http_DELETE():
        if not allow_delete(grant):
            return utils.error(
                "You are not allowed to delete this grant dossier.")
        proposal = anubis.proposal.get_proposal(grant["proposal"])
        with anubis.proposal.ProposalSaver(proposal) as saver:
            saver["grant"] = None
        utils.delete(grant)
        utils.flash_message("Deleted grant dossier.")
        return flask.redirect(
            flask.url_for("proposal.display", pid=proposal["identifier"]))
Beispiel #20
0
def access(pid):
    "Edit the access privileges for the proposal record."
    proposal = get_proposal(pid)
    if proposal is None:
        return utils.error("No such proposal.", flask.url_for("home"))
    if not allow_edit(proposal):
        return utils.error("You are not allowed to edit this proposal.")
    call = anubis.call.get_call(proposal["call"])

    if utils.http_GET():
        users = {}
        for user in proposal.get("access_view", []):
            users[user] = False
        for user in proposal.get("access_edit", []):
            users[user] = True
        return flask.render_template(
            "access.html",
            title=f"Proposal {proposal['identifier']}",
            url=flask.url_for(".access", pid=proposal["identifier"]),
            users=users,
            back_url=flask.url_for(".display", pid=proposal["identifier"]),
        )

    elif utils.http_POST():
        try:
            with ProposalSaver(doc=proposal) as saver:
                saver.set_access(form=flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(
            flask.url_for(".access", pid=proposal["identifier"]))

    elif utils.http_DELETE():
        try:
            with ProposalSaver(doc=proposal) as saver:
                saver.remove_access(form=flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(
            flask.url_for(".access", pid=proposal["identifier"]))
Beispiel #21
0
def edit(iuid):
    "Edit the decision."
    try:
        decision = get_decision(iuid)
    except KeyError:
        return utils.error("No such decision.", flask.url_for("home"))
    proposal = anubis.proposal.get_proposal(decision["proposal"])
    call = anubis.call.get_call(decision["call"])

    if utils.http_GET():
        if not allow_edit(decision):
            return utils.error("You are not allowed to edit this decision.")
        return flask.render_template("decision/edit.html",
                                     decision=decision,
                                     proposal=proposal,
                                     call=call)

    elif utils.http_POST():
        if not allow_edit(decision):
            return utils.error("You are not allowed to edit this decision.")
        try:
            # NOTE: Repeat field has not been implemented for decision.
            with DecisionSaver(doc=decision) as saver:
                saver.set_verdict(form=flask.request.form)
                saver.set_fields_values(call["decision"],
                                        form=flask.request.form)
        except ValueError as error:
            return utils.error(error)
        return flask.redirect(flask.url_for(".display", iuid=decision["_id"]))

    elif utils.http_DELETE():
        if not allow_delete(decision):
            return utils.error("You are not allowed to delete this decision.")
        with anubis.proposal.ProposalSaver(proposal) as saver:
            saver["decision"] = None
        utils.delete(decision)
        utils.flash_message("Deleted decision.")
        return flask.redirect(
            flask.url_for("proposal.display", pid=proposal["identifier"]))
Beispiel #22
0
def unarchive(iuid):
    "Unarchive the review for the proposal. Requires 'delete' privilege."
    try:
        review = get_review(iuid)
    except KeyError:
        return utils.error("No such archived review.", flask.url_for("home"))
    if not allow_delete(review):
        return utils.error("You are not allowed to unarchive this review.")
    if get_reviewer_review(
            anubis.proposal.get_proposal(review["proposal"]),
            anubis.user.get_user(review["reviewer"]),
    ):
        return utils.error(
            "Unarchived review exists for proposal and reviewer.")

    if utils.http_POST():
        try:
            with ReviewSaver(doc=review) as saver:
                saver.set_unarchived()
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".display", iuid=review["_id"]))
Beispiel #23
0
def password():
    "Set the password for a user account, and login user."
    if utils.http_GET():
        return flask.render_template(
            "user/password.html",
            username=flask.request.args.get("username"),
            code=flask.request.args.get("code"),
        )

    elif utils.http_POST():
        try:
            username = flask.request.form.get("username") or ""
            if not username:
                raise ValueError("No such user or wrong code.")
            user = get_user(username=username)
            if user is None:
                raise ValueError("No such user or wrong code.")
            if flask.g.am_admin:
                code = ""
            else:
                code = flask.request.form.get("code") or ""
                if user["password"] != f"code:{code}":
                    raise ValueError("No such user or wrong code.")
            password = flask.request.form.get("password") or ""
            if len(password) < flask.current_app.config["MIN_PASSWORD_LENGTH"]:
                raise ValueError("Too short password.")
        except ValueError as error:
            return utils.error(
                error, flask.url_for(".password", username=username,
                                     code=code))
        with UserSaver(user) as saver:
            saver.set_password(password)
        utils.flash_message("Password set.")
        if flask.g.am_admin:
            return flask.redirect(flask.url_for(".all"))
        else:
            do_login(username, password)
            return flask.redirect(flask.url_for("home"))
Beispiel #24
0
def grant_field(cid, fid):
    "Edit or delete the grant field definition."
    call = get_call(cid)
    if not call:
        return utils.error("No such call.", flask.url_for("home"))
    if not allow_edit(call):
        return utils.error("You are not allowed to edit the call.")

    if utils.http_POST():
        try:
            with CallSaver(call) as saver:
                saver.edit_grant_field(fid, flask.request.form)
        except (KeyError, ValueError) as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".grant", cid=call["identifier"]))

    elif utils.http_DELETE():
        try:
            with CallSaver(call) as saver:
                saver.delete_grant_field(fid)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".grant", cid=call["identifier"]))
Beispiel #25
0
def access(cid):
    "Edit the access privileges for the call."
    call = get_call(cid)
    if call is None:
        return utils.error("No such call.")
    if not allow_change_access(call):
        return utils.error("You are not allowed to change access for this call.")
    if utils.http_GET():
        users = {}
        for user in call.get("access_view", []):
            users[user] = False
        for user in call.get("access_edit", []):
            users[user] = True
        return flask.render_template(
            "access.html",
            title=f"Call {call['identifier']}",
            url=flask.url_for(".access", cid=call["identifier"]),
            users=users,
            back_url=flask.url_for(".display", cid=call["identifier"]),
        )

    elif utils.http_POST():
        try:
            with CallSaver(doc=call) as saver:
                saver.set_access(form=flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".access", cid=call["identifier"]))

    elif utils.http_DELETE():
        try:
            with CallSaver(doc=call) as saver:
                saver.remove_access(form=flask.request.form)
        except ValueError as error:
            utils.flash_error(error)
        return flask.redirect(flask.url_for(".access", cid=call["identifier"]))
Beispiel #26
0
def edit(iuid):
    "Edit the review for the proposal."
    try:
        review = get_review(iuid)
    except KeyError:
        return utils.error("No such review.", flask.url_for("home"))
    proposal = anubis.proposal.get_proposal(review["proposal"])
    call = anubis.call.get_call(review["call"])

    if utils.http_GET():
        if not allow_edit(review):
            return utils.error("You are not allowed to edit this review.")
        return flask.render_template("review/edit.html",
                                     review=review,
                                     proposal=proposal,
                                     call=call)

    elif utils.http_POST():
        if not allow_edit(review):
            return utils.error("You are not allowed to edit this review.")
        try:
            # NOTE: Repeat field has not been implemented for review.
            with ReviewSaver(doc=review) as saver:
                saver.set_fields_values(call["review"],
                                        form=flask.request.form)
        except ValueError as error:
            return utils.error(error)
        return flask.redirect(flask.url_for(".display", iuid=review["_id"]))

    elif utils.http_DELETE():
        if not allow_delete(review):
            return utils.error("You are not allowed to delete this review.")
        utils.delete(review)
        utils.flash_message("Deleted review.")
        return flask.redirect(
            flask.url_for("proposal.display", pid=review["proposal"]))
Beispiel #27
0
def reviewers(cid):
    "Edit the list of reviewers."
    call = get_call(cid)
    if not call:
        return utils.error("No such call.", flask.url_for("home"))

    if utils.http_GET():
        if not allow_view_details(call):
            return utils.error("You are not allowed to edit the reviewers of the call.")
        reviewers = [anubis.user.get_user(r) for r in call["reviewers"]]
        reviewer_emails = [r["email"] for r in reviewers if r["email"]]
        email_lists = {"Emails for reviewers": ", ".join(reviewer_emails)}
        return flask.render_template(
            "call/reviewers.html",
            call=call,
            reviewers=reviewers,
            email_lists=email_lists,
            allow_edit=allow_edit(call),
            allow_view_reviews=allow_view_reviews(call),
        )

    elif utils.http_POST():
        if not allow_edit(call):
            return utils.error("You are not allowed to edit the call.")
        reviewer = flask.request.form.get("reviewer")
        if not reviewer:
            return flask.redirect(flask.url_for(".display", cid=cid))
        user = anubis.user.get_user(username=reviewer)
        if user is None:
            user = anubis.user.get_user(email=reviewer)
        if user is None:
            return utils.error("No such user.")
        if anubis.proposal.get_call_user_proposal(cid, user["username"]):
            utils.flash_warning(
                "User has a proposal in the call. Allowing"
                " her to be a reviewer is questionable."
            )
        with CallSaver(call) as saver:
            try:
                saver["reviewers"].remove(user["username"])
            except ValueError:
                pass
            try:
                saver["chairs"].remove(user["username"])
            except ValueError:
                pass
            saver["reviewers"].append(user["username"])
            if utils.to_bool(flask.request.form.get("chair")):
                saver["chairs"].append(user["username"])
        return flask.redirect(flask.url_for(".reviewers", cid=call["identifier"]))

    elif utils.http_DELETE():
        if not allow_edit(call):
            return utils.error("You are not allowed to edit the call.")
        reviewer = flask.request.form.get("reviewer")
        if utils.get_docs_view(
            "reviews", "call_reviewer", [call["identifier"], reviewer]
        ):
            return utils.error(
                "Cannot remove reviewer which has reviews" " in the call."
            )
        if reviewer:
            with CallSaver(call) as saver:
                try:
                    saver["reviewers"].remove(reviewer)
                except ValueError:
                    pass
                try:
                    saver["chairs"].remove(reviewer)
                except ValueError:
                    pass
        return flask.redirect(flask.url_for(".reviewers", cid=call["identifier"]))
Beispiel #28
0
def edit(pid):
    "Edit the proposal."
    proposal = get_proposal(pid)
    if proposal is None:
        return utils.error("No such proposal.", flask.url_for("home"))
    call = anubis.call.get_call(proposal["call"])

    if utils.http_GET():
        if not allow_edit(proposal):
            return utils.error("You are not allowed to edit this proposal.")
        return flask.render_template("proposal/edit.html",
                                     proposal=proposal,
                                     call=call)

    elif utils.http_POST():
        if not allow_edit(proposal):
            return utils.error("You are not allowed to edit this proposal.")
        try:
            with ProposalSaver(proposal) as saver:
                saver["title"] = flask.request.form.get("_title") or None
                saver.set_fields_values(call["proposal"],
                                        form=flask.request.form)
        except ValueError as error:
            return utils.error(error)

        # If a repeat field was changed, then redisplay edit page.
        if saver.repeat_changed:
            return flask.redirect(
                flask.url_for(".edit", pid=proposal["identifier"]))

        if flask.request.form.get("_save") == "submit":
            proposal = get_proposal(pid, refresh=True)  # Get up-to-date info.
            try:
                with ProposalSaver(proposal) as saver:
                    saver.set_submitted()  # Tests whether allowed or not.
            except ValueError as error:
                utils.flash_error(error)
            else:
                utils.flash_message("Proposal saved and submitted.")
                send_submission_email(proposal)

        elif allow_submit(proposal) and not proposal.get("submitted"):
            utils.flash_warning("Proposal was saved but not submitted."
                                " You must explicitly submit it!")
        return flask.redirect(
            flask.url_for(".display", pid=proposal["identifier"]))

    elif utils.http_DELETE():
        if not allow_delete(proposal):
            return utils.error("You are not allowed to delete this proposal.")
        decision = anubis.decision.get_decision(proposal.get("decision"))
        if decision:
            utils.delete(decision)
        reviews = utils.get_docs_view("reviews", "proposal",
                                      proposal["identifier"])
        for review in reviews:
            utils.delete(review)
        utils.delete(proposal)
        utils.flash_message(f"Deleted proposal {pid}.")
        if flask.g.am_admin or flask.g.am_staff:
            url = flask.url_for("proposals.call", cid=call["identifier"])
        else:
            url = flask.url_for("proposals.user", username=proposal["user"])
        return flask.redirect(url)