From 7a9b336896722f3a348792c02005137ea40ea8d1 Mon Sep 17 00:00:00 2001
From: 0livd <0livd@users.noreply.github.com>
Date: Thu, 11 May 2017 18:05:18 +0200
Subject: [PATCH] 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
---
budget/templates/home.html | 4 ++++
budget/tests/tests.py | 21 +++++++++++++++++++++
budget/web.py | 4 ++++
3 files changed, 29 insertions(+)
diff --git a/budget/templates/home.html b/budget/templates/home.html
index edbee61a..c7a9d1e8 100644
--- a/budget/templates/home.html
+++ b/budget/templates/home.html
@@ -28,6 +28,9 @@
+ {% endif %}
{% endblock %}
diff --git a/budget/tests/tests.py b/budget/tests/tests.py
index e18e9c32..a1cedfad 100644
--- a/budget/tests/tests.py
+++ b/budget/tests/tests.py
@@ -44,6 +44,8 @@ class TestCase(unittest.TestCase):
# clean after testing
models.db.session.remove()
models.db.drop_all()
+ # reconfigure app with default settings
+ run.configure()
def login(self, project, password=None, test_client=None):
password = password or project
@@ -373,6 +375,25 @@ class BudgetTestCase(TestCase):
c.get("/exit")
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('', resp.data.decode('utf-8'))
+
+ # test right password
+ resp = self.app.post("/admin?goto=%2Fcreate", data={'admin_password': 'pass'})
+ self.assertIn('/create', resp.data.decode('utf-8'))
+
+ # test wrong password
+ resp = self.app.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
+ self.assertNotIn('/create', resp.data.decode('utf-8'))
+
+ # test empty password
+ resp = self.app.post("/admin?goto=%2Fcreate", data={'admin_password': ''})
+ self.assertNotIn('/create', resp.data.decode('utf-8'))
+
def test_manage_bills(self):
self.post_project("raclette")
diff --git a/budget/web.py b/budget/web.py
index c38bc26d..3bfa73a1 100644
--- a/budget/web.py
+++ b/budget/web.py
@@ -152,14 +152,18 @@ def authenticate(project_id=None):
def home():
project_form = ProjectForm()
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']
return render_template("home.html", project_form=project_form,
is_demo_project_activated=is_demo_project_activated,
+ is_admin_mode_enabled=is_admin_mode_enabled,
auth_form=auth_form, session=session)
@main.route("/create", methods=["GET", "POST"])
+@requires_admin
def create_project():
form = ProjectForm()
if request.method == "GET" and 'project_id' in request.values: