Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce that the HireFire token is present in the Flask HireFire endpoint. #61

Merged
merged 3 commits into from
Jun 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ For more help see the Hirefire `documentation`_.
Configuration
-------------

The ``hirefire`` Python package currently supports two frameworks:
Django and Tornado. Implementations for other frameworks are planned but
haven't been worked on: Flask_, Pyramid_ (PasteDeploy), WSGI_ middleware, ..
The ``hirefire`` Python package currently supports three frameworks:
Django, Tornado, and Flask_. Implementations for other frameworks are planned
but haven't been worked on: Pyramid_ (PasteDeploy), WSGI_ middleware, ..

Feel free to `contribute one`_ if you can't wait.

Expand Down Expand Up @@ -104,7 +104,7 @@ Define a ``RQProc`` subclass somewhere in your project, e.g.
See the procs API documentation if you're using another backend. Now follow
the framework specific guidelines below.

.. _`contribute one`: https://github.com/jezdez/hirefire/
.. _`contribute one`: https://github.com/ryanhiebert/hirefire/
.. _flask: http://flask.pocoo.org/
.. _Pyramid: http://www.pylonsproject.org/
.. _WSGI: http://www.python.org/dev/peps/pep-3333/
Expand Down
11 changes: 8 additions & 3 deletions hirefire/contrib/flask/blueprint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import absolute_import
from http import HTTPStatus

from flask import Blueprint, Response
from flask import abort, Blueprint, Response

from hirefire.procs import load_procs, dump_procs, HIREFIRE_FOUND

Expand All @@ -26,12 +27,16 @@ def test():
"""
return HIREFIRE_FOUND

@bp.route('/hirefire/<id>/info')
def info(id):
@bp.route('/hirefire/<secret>/info')
def info(secret):
"""
The heart of the app, returning a JSON ecoded list
of proc results.
"""

if secret != token:
abort(HTTPStatus.NOT_FOUND)

return Response(dump_procs(loaded_procs), mimetype='application/json')

return bp
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
-e .
celery
flask
redis
rq
Django
Expand Down
Empty file added tests/contrib/flask/__init__.py
Empty file.
42 changes: 42 additions & 0 deletions tests/contrib/flask/test_blueprint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Tests for the Flask blueprint factory."""

from http import HTTPStatus

import pytest

from flask import Flask


@pytest.fixture
def flask_app():
"""A Flask application instance."""

app = Flask(__name__)
app.testing = True

return app


@pytest.mark.parametrize(
"token, status_code",
(("test", HTTPStatus.OK), ("garbage", HTTPStatus.NOT_FOUND))
)
def test_hirefire_info(flask_app, monkeypatch, token, status_code):
"""Enforce the presence of the HireFire token in the info endpoint path."""

# Patch over load_procs() and dump_procs() so we don't have to worry about
# specifying actual Proc subclasses when we construct the test blueprint.
monkeypatch.setattr("hirefire.procs.load_procs", lambda *args: args)
monkeypatch.setattr("hirefire.procs.dump_procs", lambda arg: {})

from hirefire.contrib.flask.blueprint import build_hirefire_blueprint

# Normally, the second argument would be a list of Proc subclasses. We can
# pass a garbage string because we patched over load_procs() and
# dump_procs()
flask_app.register_blueprint(build_hirefire_blueprint("test", ("proc",)))

with flask_app.test_client() as client:
response = client.get(f"/hirefire/{token}/info")

assert response.status_code == status_code