Require admin permissions to access create project endpoint

When ADMIN_PASSWORD is not empty, project creation form on the
home page will be replaced by a link to the create project endpoint
so one is able to enter the admin password before filling the form
This commit is contained in:
0livd 2017-05-11 18:05:18 +02:00
parent 5880a1a3a2
commit 7a9b336896
3 changed files with 29 additions and 0 deletions

View file

@ -28,6 +28,9 @@
</form> </form>
</div> </div>
<div class="col-3 offset-md-1"> <div class="col-3 offset-md-1">
{% if is_admin_mode_enabled %}
<a href="{{ url_for(".create_project") }}">...{{ _("or create a new one") }}</a>
{% else %}
<form id="creation-form" class="form-horizontal" action="{{ url_for(".create_project") }}" method="post"> <form id="creation-form" class="form-horizontal" action="{{ url_for(".create_project") }}" method="post">
<fieldset class="form-group"> <fieldset class="form-group">
<legend>...{{ _("or create a new one") }}</legend> <legend>...{{ _("or create a new one") }}</legend>
@ -37,6 +40,7 @@
<button class="btn" type="submit">{{ _("let's get started") }}</button> <button class="btn" type="submit">{{ _("let's get started") }}</button>
</div> </div>
</form> </form>
{% endif %}
</main> </main>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -44,6 +44,8 @@ class TestCase(unittest.TestCase):
# clean after testing # clean after testing
models.db.session.remove() models.db.session.remove()
models.db.drop_all() models.db.drop_all()
# reconfigure app with default settings
run.configure()
def login(self, project, password=None, test_client=None): def login(self, project, password=None, test_client=None):
password = password or project password = password or project
@ -373,6 +375,25 @@ class BudgetTestCase(TestCase):
c.get("/exit") c.get("/exit")
self.assertNotIn('raclette', session) self.assertNotIn('raclette', session)
def test_admin_authentication(self):
run.app.config['ADMIN_PASSWORD'] = "pass"
# test the redirection to the authentication page when trying to access admin endpoints
resp = self.app.get("/create")
self.assertIn('<a href="/admin?goto=%2Fcreate">', resp.data.decode('utf-8'))
# test right password
resp = self.app.post("/admin?goto=%2Fcreate", data={'admin_password': 'pass'})
self.assertIn('<a href="/create">/create</a>', resp.data.decode('utf-8'))
# test wrong password
resp = self.app.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
self.assertNotIn('<a href="/create">/create</a>', resp.data.decode('utf-8'))
# test empty password
resp = self.app.post("/admin?goto=%2Fcreate", data={'admin_password': ''})
self.assertNotIn('<a href="/create">/create</a>', resp.data.decode('utf-8'))
def test_manage_bills(self): def test_manage_bills(self):
self.post_project("raclette") self.post_project("raclette")

View file

@ -152,14 +152,18 @@ def authenticate(project_id=None):
def home(): def home():
project_form = ProjectForm() project_form = ProjectForm()
auth_form = AuthenticationForm() auth_form = AuthenticationForm()
# If ADMIN_PASSWORD is empty we consider that admin mode is disabled
is_admin_mode_enabled = bool(current_app.config['ADMIN_PASSWORD'])
is_demo_project_activated = current_app.config['ACTIVATE_DEMO_PROJECT'] is_demo_project_activated = current_app.config['ACTIVATE_DEMO_PROJECT']
return render_template("home.html", project_form=project_form, return render_template("home.html", project_form=project_form,
is_demo_project_activated=is_demo_project_activated, is_demo_project_activated=is_demo_project_activated,
is_admin_mode_enabled=is_admin_mode_enabled,
auth_form=auth_form, session=session) auth_form=auth_form, session=session)
@main.route("/create", methods=["GET", "POST"]) @main.route("/create", methods=["GET", "POST"])
@requires_admin
def create_project(): def create_project():
form = ProjectForm() form = ProjectForm()
if request.method == "GET" and 'project_id' in request.values: if request.method == "GET" and 'project_id' in request.values: