Exemple #1
0
def run_single(pkgbase: PackageBase) -> None:
    """ A single popupdate. The given pkgbase instance will be
    refreshed after the database update is done.

    NOTE: This function is compatible only with aurweb FastAPI.

    :param pkgbase: Instance of db.PackageBase
    """
    run_variable([pkgbase])
    db.refresh(pkgbase)
def test_rendercomment_main(user: User, pkgbase: PackageBase):
    text = "Hello world! This is a comment."
    comment = create_comment(user, pkgbase, text, False)

    args = ["aurweb-rendercomment", str(comment.ID)]
    with mock.patch("sys.argv", args):
        rendercomment.main()
    db.refresh(comment)

    expected = f"<p>{text}</p>"
    assert comment.RenderedComment == expected
Exemple #3
0
def update_comment_render(comment: PackageComment) -> None:
    text = comment.Comments
    pkgbasename = comment.PackageBase.Name

    html = markdown.markdown(text,
                             extensions=[
                                 'fenced_code',
                                 LinkifyExtension(),
                                 FlysprayLinksExtension(),
                                 GitCommitsExtension(pkgbasename),
                                 HeadingExtension()
                             ])

    allowed_tags = (bleach.sanitizer.ALLOWED_TAGS +
                    ['p', 'pre', 'h4', 'h5', 'h6', 'br', 'hr'])
    html = bleach.clean(html, tags=allowed_tags)
    save_rendered_comment(comment, html)
    db.refresh(comment)
Exemple #4
0
async def terms_of_service(request: Request):
    # Query the database for terms that were previously accepted,
    # but now have a bumped Revision that needs to be accepted.
    diffs = db.query(models.Term).join(models.AcceptedTerm).filter(
        models.AcceptedTerm.Revision < models.Term.Revision).all()

    # Query the database for any terms that have not yet been accepted.
    unaccepted = db.query(models.Term).filter(
        ~models.Term.ID.in_(db.query(models.AcceptedTerm.TermsID))).all()

    for record in (diffs + unaccepted):
        db.refresh(record)

    # Translate the 'Terms of Service' part of our page title.
    _ = l10n.get_translator_for_request(request)
    title = f"AUR {_('Terms of Service')}"
    context = await make_variable_context(request, title)

    accept_needed = sorted(unaccepted + diffs)
    return render_terms_of_service(request, context, accept_needed)
Exemple #5
0
def get_user_by_name(username: str) -> User:
    """
    Query a user by its username.

    :param username: User.Username
    :return: User instance
    """
    user = db.query(User).filter(User.Username == username).first()
    if not user:
        raise HTTPException(status_code=int(HTTPStatus.NOT_FOUND))
    return db.refresh(user)
Exemple #6
0
async def account_edit(request: Request, username: str):
    user = db.query(models.User, models.User.Username == username).first()

    response = cannot_edit(request, user)
    if response:
        return response

    context = await make_variable_context(request, "Accounts")
    context["user"] = db.refresh(user)

    context = make_account_form_context(context, request, user, dict())
    return render_template(request, "account/edit.html", context)
Exemple #7
0
async def terms_of_service_post(request: Request,
                                accept: bool = Form(default=False)):
    # Query the database for terms that were previously accepted,
    # but now have a bumped Revision that needs to be accepted.
    diffs = db.query(models.Term).join(models.AcceptedTerm).filter(
        models.AcceptedTerm.Revision < models.Term.Revision).all()

    # Query the database for any terms that have not yet been accepted.
    unaccepted = db.query(models.Term).filter(
        ~models.Term.ID.in_(db.query(models.AcceptedTerm.TermsID))).all()

    if not accept:
        # Translate the 'Terms of Service' part of our page title.
        _ = l10n.get_translator_for_request(request)
        title = f"AUR {_('Terms of Service')}"
        context = await make_variable_context(request, title)

        # We already did the database filters here, so let's just use
        # them instead of reiterating the process in terms_of_service.
        accept_needed = sorted(unaccepted + diffs)
        return render_terms_of_service(
            request, context, util.apply_all(accept_needed, db.refresh))

    with db.begin():
        # For each term we found, query for the matching accepted term
        # and update its Revision to the term's current Revision.
        for term in diffs:
            db.refresh(term)
            accepted_term = request.user.accepted_terms.filter(
                models.AcceptedTerm.TermsID == term.ID).first()
            accepted_term.Revision = term.Revision

        # For each term that was never accepted, accept it!
        for term in unaccepted:
            db.refresh(term)
            db.create(models.AcceptedTerm, User=request.user,
                      Term=term, Revision=term.Revision)

    return RedirectResponse("/", status_code=HTTPStatus.SEE_OTHER)
Exemple #8
0
def request(pkgbase: PackageBase, type: str, comments: str, merge_into: str,
            context: Dict[str, Any]) -> None:
    if not comments:
        raise ValidationError(["The comment field must not be empty."])

    if type == "merge":
        # Perform merge-related checks.
        if not merge_into:
            # TODO: This error needs to be translated.
            raise ValidationError(
                ['The "Merge into" field must not be empty.'])

        target = db.query(PackageBase).filter(
            PackageBase.Name == merge_into).first()
        if not target:
            # TODO: This error needs to be translated.
            raise ValidationError(
                ["The package base you want to merge into does not exist."])

        db.refresh(target)
        if target.ID == pkgbase.ID:
            # TODO: This error needs to be translated.
            raise ValidationError(
                ["You cannot merge a package base into itself."])
Exemple #9
0
def get_pkgbase_comment(pkgbase: models.PackageBase, id: int) \
        -> models.PackageComment:
    comment = pkgbase.comments.filter(models.PackageComment.ID == id).first()
    if not comment:
        raise HTTPException(status_code=HTTPStatus.NOT_FOUND)
    return db.refresh(comment)
Exemple #10
0
async def passreset_post(request: Request,
                         user: str = Form(...),
                         resetkey: str = Form(default=None),
                         password: str = Form(default=None),
                         confirm: str = Form(default=None)):
    context = await make_variable_context(request, "Password Reset")

    # The user parameter being required, we can match against
    criteria = or_(models.User.Username == user, models.User.Email == user)
    db_user = db.query(models.User,
                       and_(criteria, models.User.Suspended == 0)).first()
    if db_user is None:
        context["errors"] = ["Invalid e-mail."]
        return render_template(request, "passreset.html", context,
                               status_code=HTTPStatus.NOT_FOUND)

    db.refresh(db_user)
    if resetkey:
        context["resetkey"] = resetkey

        if not db_user.ResetKey or resetkey != db_user.ResetKey:
            context["errors"] = ["Invalid e-mail."]
            return render_template(request, "passreset.html", context,
                                   status_code=HTTPStatus.NOT_FOUND)

        if not user or not password:
            context["errors"] = ["Missing a required field."]
            return render_template(request, "passreset.html", context,
                                   status_code=HTTPStatus.BAD_REQUEST)

        if password != confirm:
            # If the provided password does not match the provided confirm.
            context["errors"] = ["Password fields do not match."]
            return render_template(request, "passreset.html", context,
                                   status_code=HTTPStatus.BAD_REQUEST)

        if len(password) < models.User.minimum_passwd_length():
            # Translate the error here, which simplifies error output
            # in the jinja2 template.
            _ = get_translator_for_request(request)
            context["errors"] = [_(
                "Your password must be at least %s characters.") % (
                str(models.User.minimum_passwd_length()))]
            return render_template(request, "passreset.html", context,
                                   status_code=HTTPStatus.BAD_REQUEST)

        # We got to this point; everything matched up. Update the password
        # and remove the ResetKey.
        with db.begin():
            db_user.ResetKey = str()
            if db_user.session:
                db.delete(db_user.session)
            db_user.update_password(password)

        # Render ?step=complete.
        return RedirectResponse(url="/passreset?step=complete",
                                status_code=HTTPStatus.SEE_OTHER)

    # If we got here, we continue with issuing a resetkey for the user.
    resetkey = generate_resetkey()
    with db.begin():
        db_user.ResetKey = resetkey

    ResetKeyNotification(db_user.ID).send()

    # Render ?step=confirm.
    return RedirectResponse(url="/passreset?step=confirm",
                            status_code=HTTPStatus.SEE_OTHER)
Exemple #11
0
async def account_edit_post(request: Request,
                            username: str,
                            U: str = Form(default=str()),  # Username
                            J: bool = Form(default=False),
                            E: str = Form(default=str()),  # Email
                            H: str = Form(default=False),    # Hide Email
                            BE: str = Form(default=None),    # Backup Email
                            R: str = Form(default=None),     # Real Name
                            HP: str = Form(default=None),    # Homepage
                            I: str = Form(default=None),     # IRC Nick
                            K: str = Form(default=None),     # PGP Key
                            L: str = Form(aurweb.config.get(
                                "options", "default_lang")),
                            TZ: str = Form(aurweb.config.get(
                                "options", "default_timezone")),
                            P: str = Form(default=str()),    # New Password
                            C: str = Form(default=None),     # Password Confirm
                            PK: str = Form(default=None),    # PubKey
                            CN: bool = Form(default=False),  # Comment Notify
                            UN: bool = Form(default=False),  # Update Notify
                            ON: bool = Form(default=False),  # Owner Notify
                            T: int = Form(default=None),
                            passwd: str = Form(default=str())):
    user = db.query(models.User).filter(
        models.User.Username == username).first()
    response = cannot_edit(request, user)
    if response:
        return response

    context = await make_variable_context(request, "Accounts")
    context["user"] = db.refresh(user)

    args = dict(await request.form())
    args["K"] = args.get("K", str()).replace(" ", "")

    context = make_account_form_context(context, request, user, args)
    ok, errors = process_account_form(request, user, args)

    if PK:
        context["ssh_pks"] = [PK]

    if not passwd:
        context["errors"] = ["Invalid password."]
        return render_template(request, "account/edit.html", context,
                               status_code=HTTPStatus.BAD_REQUEST)

    if not ok:
        context["errors"] = errors
        return render_template(request, "account/edit.html", context,
                               status_code=HTTPStatus.BAD_REQUEST)

    updates = [
        update.simple,
        update.language,
        update.timezone,
        update.ssh_pubkey,
        update.account_type,
        update.password
    ]

    for f in updates:
        f(**args, request=request, user=user, context=context)

    if not errors:
        context["complete"] = True

    # Update cookies with requests, in case they were changed.
    response = render_template(request, "account/edit.html", context)
    return cookies.update_response_cookies(request, response,
                                           aurtz=TZ, aurlang=L)