Skip to content
Open
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
2 changes: 1 addition & 1 deletion ihatemoney/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -644,4 +644,4 @@ footer .icon svg {

.edit-project .custom-file {
margin-bottom: 2em;
}
}
14 changes: 14 additions & 0 deletions ihatemoney/templates/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ <h2>{{ _("Manage your shared <br />expenses, easily") }}</h2>
</header>
<main class="row home">
<div class="card-deck ml-auto mr-auto">
{% if 'projects' in session %}
<div class="card">
<div class="card-header">
{{ _("Open a connected project") }}
</div>
<div class="card-body">
<ul>
{% for id, name in session['projects'].items() %}
<li><a href="{{ url_for("main.list_bills", project_id=id )}}">{{name}}</a>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
<div class="card">
<div class="card-header">
{{ _("Log in to an existing project") }}
Expand Down
56 changes: 56 additions & 0 deletions ihatemoney/tests/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from ihatemoney.tests.common.help_functions import em_surround
from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase
from flask import url_for


class TestAPI(IhatemoneyTestCase):
Expand Down Expand Up @@ -1079,3 +1080,58 @@ def test_default_bill_type(self):
# Bill type should now be "Expense"
got = json.loads(req.data.decode("utf-8"))
assert got["bill_type"] == "Expense"

def test_project_list_redirection(self):
self.post_project("project1", default_currency="USD")
self.post_project("project2", default_currency="EUR")

# Step 2: Log into these projects (simulate a user accessing them)
self.login("project1")
self.login("project2")

# Step 3: Access the homepage where the project list should be displayed
response = self.client.get("/")
self.assertStatus(200, response)
page_content = response.data.decode("utf-8")

# Check that both project names appear in the list
assert "project1" in page_content
assert "project2" in page_content

# Step 4: Simulate clicking on "project1" by visiting its link
response = self.client.get("/project1/")
self.assertStatus(200, response) # Should load the project page

assert "project1" in response.data.decode("utf-8") # Project content should be visible

def test_get_auth(self):
"""
Redirects to logged in projects
"""
self.create_project("test-project")
self.login("test-project")

req = self.client.get(url_for('main.list_bills', project_id='test-project'))
self.assertStatus(200, req)

def test_post_auth_wrong_password(self):
"""
Rejects wrong passwords for projects
in the session
"""
self.create_project("project1", password="a")
req = self.login("project1", "b")


assert req.request.path == '/authenticate'

def test_post_auth_correct_password(self):
"""
Accepts correct passwords for projects
in the session
"""
self.create_project("project1", password="a")
req = self.login("project1", "a")

assert req.request.path == '/project1/'

9 changes: 5 additions & 4 deletions ihatemoney/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ def join_project(token):
def authenticate(project_id=None):
"""Authentication form"""
form = AuthenticationForm()
is_post_auth = request.method == "POST" and form.validate()

if not form.id.data and request.args.get("project_id"):
form.id.data = request.args["project_id"]
Expand All @@ -270,14 +271,13 @@ def authenticate(project_id=None):
return render_template(
"authenticate.html", form=form, create_project=project_id
)

# if credentials are already in session, redirect
if session.get(project_id):
# if credentials are already in session and no password is provided, redirect
if session.get(project_id) and not is_post_auth:
setattr(g, "project", project)
return redirect(url_for(".list_bills"))

# else do form authentication authentication
is_post_auth = request.method == "POST" and form.validate()
if is_post_auth and check_password_hash(project.password, form.password.data):
set_authorized_project(project)
setattr(g, "project", project)
Expand All @@ -290,6 +290,7 @@ def authenticate(project_id=None):


def get_project_form():
fancy = {'complexity':'Cyclo. compl.', 'churn': 'Churn', 'comments_ratio': 'Ratio', 'loc': 'LOC', 'dit': 'DIT', 'cbo': 'CBO', 'vulns': 'Vuln.', 'smells': 'Smells'}
if current_app.config.get("ENABLE_CAPTCHA", False):
return ProjectFormWithCaptcha()
return ProjectForm()
Expand Down