Skip to content

Commit

Permalink
Always authentify projects using a lowercase ID. (#925)
Browse files Browse the repository at this point in the history
Fixes #920
  • Loading branch information
almet committed Nov 21, 2021
1 parent 4d6a5aa commit beac10b
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 17 deletions.
6 changes: 3 additions & 3 deletions ihatemoney/api/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ def need_auth(f):
@wraps(f)
def wrapper(*args, **kwargs):
auth = request.authorization
project_id = kwargs.get("project_id")
project_id = kwargs.get("project_id").lower()

# Use Basic Auth
if auth and project_id and auth.username == project_id:
project = Project.query.get(auth.username)
if auth and project_id and auth.username.lower() == project_id:
project = Project.query.get(auth.username.lower())
if project and check_password_hash(project.password, auth.password):
# The whole project object will be passed instead of project_id
kwargs.pop("project_id")
Expand Down
30 changes: 16 additions & 14 deletions ihatemoney/tests/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,15 @@ def api_create(
password = password or name
contact = contact or f"{name}@notmyidea.org"

data = {
"name": name,
"id": id,
"password": password,
"contact_email": contact,
}
if default_currency:
data = {
"name": name,
"id": id,
"password": password,
"contact_email": contact,
"default_currency": default_currency,
}
else:
data = {
"name": name,
"id": id,
"password": password,
"contact_email": contact,
}
data["default_currency"] = default_currency

return self.client.post(
"/api/projects",
data=data,
Expand Down Expand Up @@ -905,6 +899,14 @@ def test_log_created_from_api_call(self):
self.assertEqual(resp.data.decode("utf-8").count("<td> -- </td>"), 2)
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__":
unittest.main()
13 changes: 13 additions & 0 deletions ihatemoney/tests/budget_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,19 @@ def test_authentication(self):
self.assertNotIn("Authentication", resp.data.decode("utf-8"))
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):
self.app.config["ADMIN_PASSWORD"] = generate_password_hash("pass")
# Disable public project creation so we have an admin endpoint to test
Expand Down

0 comments on commit beac10b

Please sign in to comment.