Exemplo n.º 1
0
def search(app, request, doctype):
    if doctype not in app.search.types:
        raise NotFound

    limit = app.search.types[doctype].SEARCH_LIMIT

    query = request.args.get("q")
    try:
        page = int(request.args.get("page", 1))
    except ValueError:
        raise NotFound
    if page <= 0:
        page = 1
    offset = (page - 1) * limit

    results = app.search.types[doctype].search(query, limit, offset)
    total = results.get("hits", {}).get("total", 0)

    url_partial = functools.partial(
        url_for, request, 'warehouse.search.views.search', doctype='project',
        q=query)
    pages = SearchPagination(page, total, limit, url_partial)

    return render_response(
        app,
        request,
        "search/results.html",
        query=query, total=total, pages=pages,
        results=[r["_source"] for r in results["hits"]["hits"]],
    )
Exemplo n.º 2
0
def index(app, request):
    return render_response(
        app, request, "index.html",
        project_count=app.db.packaging.get_project_count(),
        download_count=app.db.packaging.get_download_count(),
        recently_updated=app.db.packaging.get_recently_updated(),
    )
Exemplo n.º 3
0
def search(app, request, doctype):
    if doctype not in app.search.types:
        raise NotFound

    limit = app.search.types[doctype].SEARCH_LIMIT

    query = request.args.get("q")
    try:
        page = int(request.args.get("page", 1))
    except ValueError:
        raise NotFound
    if page <= 0:
        page = 1
    offset = (page - 1) * limit

    results = app.search.types[doctype].search(query, limit, offset)
    total = results.get("hits", {}).get("total", 0)

    url_partial = functools.partial(url_for,
                                    request,
                                    'warehouse.search.views.search',
                                    doctype='project',
                                    q=query)
    pages = SearchPagination(page, total, limit, url_partial)

    return render_response(
        app,
        request,
        "search/results.html",
        query=query,
        total=total,
        pages=pages,
        results=[r["_source"] for r in results["hits"]["hits"]],
    )
Exemplo n.º 4
0
def index(app, request):
    return render_response(
        app, request, "index.html",
        project_count=app.models.packaging.get_project_count(),
        download_count=app.models.packaging.get_download_count(),
        recently_updated=app.models.packaging.get_recently_updated(),
    )
Exemplo n.º 5
0
def index(app, request):
    projects = app.db.packaging.all_projects()
    resp = render_response(
        app, request, "legacy/simple/index.html",
        projects=projects,
    )

    # Add a header that points to the last serial
    serial = app.db.packaging.get_last_serial()
    resp.headers.add("X-PyPI-Last-Serial", serial)

    return resp
Exemplo n.º 6
0
def login(app, request):
    form = LoginForm(
        request.form,
        authenticator=app.db.accounts.user_authenticate,
        translations=app.translations,
    )

    if request.method == "POST" and form.validate():
        # Get the user's ID, this is what we will use as the identifier anytime
        # we need to securely reference the user within the database.
        user_id = app.db.accounts.get_user_id(form.username.data)

        if request.session.get("user.id") != user_id:
            # To avoid reusing another user's session data, clear the session
            # data if the existing session corresponds to a different
            # authenticated user.
            request.session.clear()

        # Cycle the session key to prevent session fixation attacks from
        # crossing an authentication boundary
        request.session.cycle()

        # Cycle the CSRF token to prevent a CSRF via session fixation attack
        # from crossing an authentication boundary
        csrf_cycle(request.session)

        # Log the user in by storing their user id in their session
        request.session["user.id"] = user_id

        # We'll want to redirect the user with a 303 once we've completed the
        # log in process.
        resp = redirect_next(
            request,
            default=url_for(request, "warehouse.views.index"),
        )

        # Store the user's name in a cookie so that the client side can use
        # it for display purposes. This value **MUST** not be used for any
        # sort of access control.
        resp.set_cookie("username", form.username.data)

        # Return our prepared response to the user
        return resp

    # Either this is a GET request or it is a POST request with a failing form
    # validation. Either way we want to simply render our template with the
    # form available.
    return render_response(
        app, request, "accounts/login.html",
        form=form,
        next=request.values.get("next"),
    )
Exemplo n.º 7
0
def test_render_response():
    template = pretend.stub(render=pretend.call_recorder(lambda **k: "test"))
    app = pretend.stub(
        templates=pretend.stub(
            get_template=pretend.call_recorder(lambda t: template),
        ),
    )
    request = pretend.stub()

    resp = render_response(app, request, "template.html", foo="bar")

    assert resp.data == b"test"
    assert app.templates.get_template.calls == [pretend.call("template.html")]
    assert template.render.calls == [pretend.call(foo="bar", url_for=mock.ANY)]
Exemplo n.º 8
0
def index(app, request):
    projects = app.models.packaging.all_projects()
    resp = render_response(
        app,
        request,
        "legacy/simple/index.html",
        projects=projects,
    )

    # Add a header that points to the last serial
    serial = app.models.packaging.get_last_serial()
    resp.headers.add("X-PyPI-Last-Serial", serial)

    return resp
Exemplo n.º 9
0
def index(app, request):
    projects = app.models.packaging.all_projects()
    resp = render_response(
        app, request, "legacy/simple/index.html",
        projects=projects,
    )

    # Add our surrogate key headers for Fastly
    if app.config.fastly:
        resp.headers.add("Surrogate-Key", "simple-index")

    # Add a header that points to the last serial
    serial = app.models.packaging.get_last_serial()
    resp.headers.add("X-PyPI-Last-Serial", serial)

    return resp
Exemplo n.º 10
0
def packages_rss(app, request):
    """Dump the last N days' new projects as an RSS feed.
    """
    releases = app.db.packaging.get_recent_projects(num=40)
    for release in releases:
        # TODO update _force_external to _external when Flask-ification is done
        url = url_for(
            request, "warehouse.packaging.views.project_detail", project_name=release["name"], _force_external=True
        )
        release.update(dict(url=url))

    response = render_response(
        app, request, "legacy/rss.xml", description="new projects", releases=releases, site=app.config.site
    )
    response.mimetype = "text/xml; charset=utf-8"
    # TODO: throw in a last-modified header too?
    return response
Exemplo n.º 11
0
def rss(app, request):
    """Dump the last N days' updates as an RSS feed.
    """
    releases = app.db.packaging.get_recently_updated(num=40)
    for release in releases:
        values = dict(project_name=release['name'], version=release['version'])
        url = app.urls.build('warehouse.packaging.views.project_detail',
                             values, force_external=True)
        release.update(dict(url=url))

    response = render_response(
        app, request, "legacy/rss.xml",
        description='package updates',
        releases=releases,
        site=app.config.site,
    )
    response.mimetype = 'text/xml; charset=utf-8'
    # TODO: throw in a last-modified header too?
    return response
Exemplo n.º 12
0
def user_profile(app, request, username):
    user = app.db.accounts.get_user(username)

    if user is None:
        raise NotFound("Could not find user {}".format(username))

    if user["username"] != username:
        return redirect(
            url_for(
                request,
                "warehouse.accounts.views.user_profile",
                username=user["username"],
            ),
            code=301,
        )

    return render_response(
        app, request, "accounts/profile.html",
        user=user,
        projects=app.db.packaging.get_projects_for_user(user["username"]),
    )
Exemplo n.º 13
0
def test_render_response():
    template = pretend.stub(render=pretend.call_recorder(lambda **k: "test"))
    app = pretend.stub(
        config=pretend.stub(),
        templates=pretend.stub(
            get_template=pretend.call_recorder(lambda t: template), ),
    )
    request = pretend.stub()

    resp = render_response(app, request, "template.html", foo="bar")

    assert resp.data == b"test"
    assert app.templates.get_template.calls == [pretend.call("template.html")]
    assert template.render.calls == [
        pretend.call(
            foo="bar",
            config=app.config,
            gravatar_url=mock.ANY,
            url_for=mock.ANY,
            static_url=mock.ANY,
        ),
    ]
Exemplo n.º 14
0
def test_render_response():
    template = pretend.stub(render=pretend.call_recorder(lambda **k: "test"))
    app = pretend.stub(
        config=pretend.stub(),
        templates=pretend.stub(
            get_template=pretend.call_recorder(lambda t: template),
        ),
    )
    request = pretend.stub()

    resp = render_response(app, request, "template.html", foo="bar")

    assert resp.data == b"test"
    assert app.templates.get_template.calls == [pretend.call("template.html")]
    assert template.render.calls == [
        pretend.call(
            foo="bar",
            config=app.config,
            csrf_token=mock.ANY,
            gravatar_url=mock.ANY,
            url_for=mock.ANY,
            static_url=mock.ANY,
        ),
    ]
Exemplo n.º 15
0
def logout(app, request):
    if request.method == "POST":
        # Delete our session, the user is logging out and we no longer want it
        request.session.delete()

        # We'll want to redirect the user with a 303 once we've completed the
        # log in process.
        resp = redirect_next(
            request,
            default=url_for(request, "warehouse.views.index"),
        )

        # Delete the username cookie, the user is logging out and we no longer
        # want to store the username that they used when they were logged in.
        resp.delete_cookie("username")

        # Return our prepared response to the now logged out user
        return resp

    # This is a simple GET request, so we just want to render the template
    return render_response(
        app, request, "accounts/logout.html",
        next=request.values.get("next"),
    )
Exemplo n.º 16
0
def project_detail(app, request, project_name, version=None):
    # Get the real project name for this project
    project = app.db.packaging.get_project(project_name)

    if project is None:
        raise NotFound("Cannot find a project named {}".format(project_name))

    # Look up all the releases for the given project
    releases = app.db.packaging.get_releases(project)

    if not releases:
        # If there are no releases then we need to return a simpler response
        # that simply states the project exists but that there is no versions
        # registered.
        raise NotFound(
            "There are no releases registered for the {} project".format(
                project,
            ),
        )

    if project != project_name:
        # We've found the project, and the version exists, but the project name
        # isn't quite right so we'll redirect them to the correct one.
        return redirect(
            url_for(
                request,
                "warehouse.packaging.views.project_detail",
                project_name=project,
                version=version,
            ),
            code=301,
        )

    if version is None:
        # If there's no version specified, then we use the latest version
        version = releases[0]["version"]
    elif not version in (r["version"] for r in releases):
        # If a version was specified then we need to ensure it's one of the
        # versions this project has, else raise a NotFound
        raise NotFound(
            "Cannot find the {} version of the {} project".format(
                version,
                project,
            ),
        )

    # Get the release data for the version
    release = app.db.packaging.get_release(project, version)

    if release.get("description"):
        # Render the project description
        description_html, rendered = readme.rst.render(release["description"])

        if not rendered:
            description_html = description_html.replace("\n", "<br>")

        if app.config.camo:
            description_html = camouflage_images(
                app.config.camo.url,
                app.config.camo.key,
                description_html,
            )
    else:
        description_html = ""

    # Mark our description_html as safe as it's already been cleaned by bleach
    description_html = jinja2.Markup(description_html)

    return render_response(
        app, request, "projects/detail.html",
        project=project,
        release=release,
        releases=releases,
        description_html=description_html,
        download_counts=app.db.packaging.get_download_counts(project),
        downloads=app.db.packaging.get_downloads(project, version),
        classifiers=app.db.packaging.get_classifiers(project, version),
        documentation=app.db.packaging.get_documentation_url(project),
        bugtracker=app.db.packaging.get_bugtrack_url(project),
        maintainers=app.db.packaging.get_users_for_project(project),
    )
Exemplo n.º 17
0
def project(app, request, project_name):
    # Get the real project name for this project
    project = app.db.packaging.get_project(project_name)

    if project is None:
        raise NotFound("{} does not exist".format(project_name))

    # Generate the Package URLs for the packages we've hosted
    file_urls = app.db.packaging.get_file_urls(project)

    # Determine what the hosting mode is for this package
    hosting_mode = app.db.packaging.get_hosting_mode(project)

    project_urls = []
    if hosting_mode in {"pypi-scrape-crawl", "pypi-scrape"}:
        rel_prefix = "" if hosting_mode == "pypi-scrape-crawl" else "ext-"
        home_rel = "{}homepage".format(rel_prefix)
        download_rel = "{}download".format(rel_prefix)

        # Generate the Homepage and Download URL links
        release_urls = app.db.packaging.get_release_urls(project)
        for version, (home_page, download_url) in release_urls.items():
            if home_page and home_page != "UNKNOWN":
                project_urls.append({
                    "rel": home_rel,
                    "url": home_page,
                    "name": "{} home_page".format(version),
                })

            if download_url and download_url != "UNKNOWN":
                project_urls.append({
                    "rel": download_rel,
                    "url": download_url,
                    "name": "{} download_url".format(version),
                })

    # Fetch the explicitly provided URLs
    external_urls = app.db.packaging.get_external_urls(project)

    resp = render_response(
        app, request,
        "legacy/simple/detail.html",
        project=project,
        files=file_urls,
        project_urls=project_urls,
        external_urls=external_urls,
    )

    # Add a header that points to the last serial
    serial = app.db.packaging.get_last_serial(project)
    resp.headers.add("X-PyPI-Last-Serial", serial)

    # Add a Link header to point at the canonical URL
    can_url = url_for(
        request, "warehouse.legacy.simple.project",
        project_name=project,
        _force_external=True,
    )
    resp.headers.add("Link", "<" + can_url + ">", rel="canonical")

    return resp
Exemplo n.º 18
0
def project(app, request, project_name):
    # Get the real project name for this project
    project = app.models.packaging.get_project(project_name)

    if project is None:
        raise NotFound("{} does not exist".format(project_name))

    # Generate the Package URLs for the packages we've hosted
    file_urls = app.models.packaging.get_file_urls(project)

    # Determine what the hosting mode is for this package
    hosting_mode = app.models.packaging.get_hosting_mode(project)

    project_urls = []
    if hosting_mode in {"pypi-scrape-crawl", "pypi-scrape"}:
        rel_prefix = "" if hosting_mode == "pypi-scrape-crawl" else "ext-"
        home_rel = "{}homepage".format(rel_prefix)
        download_rel = "{}download".format(rel_prefix)

        # Generate the Homepage and Download URL links
        release_urls = app.models.packaging.get_release_urls(project)
        for version, (home_page, download_url) in release_urls.items():
            if home_page and home_page != "UNKNOWN":
                project_urls.append({
                    "rel": home_rel,
                    "url": home_page,
                    "name": "{} home_page".format(version),
                })

            if download_url and download_url != "UNKNOWN":
                project_urls.append({
                    "rel": download_rel,
                    "url": download_url,
                    "name": "{} download_url".format(version),
                })

    # Fetch the explicitly provided URLs
    external_urls = app.models.packaging.get_external_urls(project)

    resp = render_response(
        app,
        request,
        "legacy/simple/detail.html",
        project=project,
        files=file_urls,
        project_urls=project_urls,
        external_urls=external_urls,
    )

    # Add a header that points to the last serial
    serial = app.models.packaging.get_last_serial(project)
    resp.headers.add("X-PyPI-Last-Serial", serial)

    # Add a Link header to point at the canonical URL
    can_url = url_for(
        request,
        "warehouse.legacy.simple.project",
        project_name=project,
        _force_external=True,
    )
    resp.headers.add("Link", "<" + can_url + ">", rel="canonical")

    return resp