Always authentify projects using a lowercase ID. (#925)

Fixes #920
This commit is contained in:
Alexis Metaireau 2021-11-21 17:13:26 +01:00 committed by GitHub
parent 4d6a5aaa27
commit beac10be0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 17 deletions

View file

@ -18,11 +18,11 @@ def need_auth(f):
@wraps(f) @wraps(f)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
auth = request.authorization auth = request.authorization
project_id = kwargs.get("project_id") project_id = kwargs.get("project_id").lower()
# Use Basic Auth # Use Basic Auth
if auth and project_id and auth.username == project_id: if auth and project_id and auth.username.lower() == project_id:
project = Project.query.get(auth.username) project = Project.query.get(auth.username.lower())
if project and check_password_hash(project.password, auth.password): if project and check_password_hash(project.password, auth.password):
# The whole project object will be passed instead of project_id # The whole project object will be passed instead of project_id
kwargs.pop("project_id") kwargs.pop("project_id")

View file

@ -18,21 +18,15 @@ class APITestCase(IhatemoneyTestCase):
password = password or name password = password or name
contact = contact or f"{name}@notmyidea.org" contact = contact or f"{name}@notmyidea.org"
data = {
"name": name,
"id": id,
"password": password,
"contact_email": contact,
}
if default_currency: if default_currency:
data = { data["default_currency"] = default_currency
"name": name,
"id": id,
"password": password,
"contact_email": contact,
"default_currency": default_currency,
}
else:
data = {
"name": name,
"id": id,
"password": password,
"contact_email": contact,
}
return self.client.post( return self.client.post(
"/api/projects", "/api/projects",
data=data, data=data,
@ -905,6 +899,14 @@ class APITestCase(IhatemoneyTestCase):
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2) self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2)
self.assertNotIn("127.0.0.1", resp.data.decode("utf-8")) self.assertNotIn("127.0.0.1", resp.data.decode("utf-8"))
def test_project_creation_with_mixed_case(self):
self.api_create("Raclette")
# get information about it
resp = self.client.get(
"/api/projects/Raclette", headers=self.get_auth("Raclette")
)
self.assertStatus(200, resp)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View file

@ -511,6 +511,19 @@ class BudgetTestCase(IhatemoneyTestCase):
self.assertNotIn("Authentication", resp.data.decode("utf-8")) self.assertNotIn("Authentication", resp.data.decode("utf-8"))
self.assertTrue(session["is_admin"]) self.assertTrue(session["is_admin"])
def test_authentication_with_upper_case(self):
self.create_project("Raclette")
# try to connect with the right credentials should work
with self.app.test_client() as c:
resp = c.post(
"/authenticate", data={"id": "Raclette", "password": "Raclette"}
)
self.assertNotIn("Authentication", resp.data.decode("utf-8"))
self.assertIn("Raclette", session)
self.assertTrue(session["Raclette"])
def test_admin_authentication(self): def test_admin_authentication(self):
self.app.config["ADMIN_PASSWORD"] = generate_password_hash("pass") self.app.config["ADMIN_PASSWORD"] = generate_password_hash("pass")
# Disable public project creation so we have an admin endpoint to test # Disable public project creation so we have an admin endpoint to test