Skip to content

Commit

Permalink
fix a bunch of tests
Browse files Browse the repository at this point in the history
  • Loading branch information
GDay committed Nov 7, 2023
1 parent d3f8f47 commit 2dbb59c
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 158 deletions.
4 changes: 2 additions & 2 deletions back/admin/people/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2638,7 +2638,7 @@ def test_employee_can_only_login_with_access(
):
employee1 = employee_factory()

url = reverse("login")
url = reverse("account_login")
data = {"username": employee1.email, "password": "test"}
client.post(url, data=data, follow=True)

Expand All @@ -2662,7 +2662,7 @@ def test_employee_can_only_login_with_access(
assert not user.is_authenticated

# Try logging in again with employee account
url = reverse("login")
url = reverse("account_login")
client.post(url, data=data, follow=True)

user = auth.get_user(client)
Expand Down
51 changes: 0 additions & 51 deletions back/admin/settings/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,57 +473,6 @@ def test_sending_test_colleague_welcome_message(
]


@pytest.mark.django_db
def test_otp_view(client, admin_factory):
admin_user1 = admin_factory()
client.force_login(admin_user1)

url = reverse("settings:personal-otp")
response = client.get(url)

assert "Please scan the code below" in response.content.decode()

# Secret is necessary to set up TOTP
assert admin_user1.totp_secret in response.content.decode()
assert "6 digit OTP code" in response.content.decode()


@pytest.mark.django_db
@patch("pyotp.TOTP.verify", Mock(return_value=False))
def test_enable_otp_view_wrong_otp(client, admin_factory):
admin_user1 = admin_factory()
client.force_login(admin_user1)

url = reverse("settings:personal-otp")
response = client.post(url, {"otp": 223456}, follow=True)

admin_user1.refresh_from_db()

assert not admin_user1.requires_otp
assert "OTP token was not correct." in response.content.decode()


@pytest.mark.django_db
@patch("pyotp.TOTP.verify", Mock(return_value=True))
def test_enable_otp_view_correct_otp(client, admin_factory):
admin_user1 = admin_factory()
client.force_login(admin_user1)

url = reverse("settings:personal-otp")
response = client.post(url, {"otp": 223456}, follow=True)

admin_user1.refresh_from_db()

assert "Please copy and save the keys below. These will only show once"
assert len(response.context["keys"]) == 10
assert admin_user1.requires_otp
assert "OTP token was not correct." not in response.content.decode()

response = client.get(url)

assert "OTP has been enabled for your account" not in response.content.decode()


@pytest.mark.django_db
def test_integration_list(client, admin_factory):
admin_user1 = admin_factory()
Expand Down
2 changes: 0 additions & 2 deletions back/fixtures/all.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
"is_active": true,
"is_introduced_to_colleagues": false,
"sent_preboarding_details": false,
"totp_secret": "",
"requires_otp": false,
"seen_updates": "2021-04-02T00:00:00Z",
"completed_tasks": 0,
"total_tasks": 0,
Expand Down
2 changes: 1 addition & 1 deletion back/organization/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,4 @@ def form_valid(self, form):
demo_user.start_day = timezone.now().date() + timedelta(days=5)
demo_user.save()

return redirect("login")
return redirect("account_login")
110 changes: 14 additions & 96 deletions back/user_auth/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from unittest.mock import Mock, patch

from allauth.mfa.models import Authenticator
import jwt
import pytest
from django.contrib import auth
Expand Down Expand Up @@ -56,7 +57,7 @@ def test_login_data_validation(email, password, logged_in, client, new_hire_fact
new_hire.set_password("strong_pass")
new_hire.save()

url = reverse("login")
url = reverse("account_login")
data = {"username": email, "password": password}
client.post(url, data=data, follow=True)
user = auth.get_user(client)
Expand All @@ -78,7 +79,7 @@ def test_redirect_after_login(role, redirect_url, client, new_hire_factory):
new_hire.set_password("strong_pass")
new_hire.save()

url = reverse("login")
url = reverse("account_login")
data = {"username": new_hire.email, "password": "strong_pass"}
response = client.post(url, data=data, follow=True)
user = auth.get_user(client)
Expand All @@ -93,7 +94,7 @@ def test_credentials_setting(client, new_hire_factory):
org = Organization.object.get()
org.credentials_login = True
org.save()
response = client.get(reverse("login"))
response = client.get(reverse("account_login"))

# Login form should be here
assert "id_username" in response.content.decode()
Expand All @@ -105,14 +106,14 @@ def test_credentials_setting(client, new_hire_factory):
org.save()

# Login form should be gone
response = client.get(reverse("login"))
response = client.get(reverse("account_login"))
assert "id_username" not in response.content.decode()
assert "id_password" not in response.content.decode()
assert "Log in" not in response.content.decode()

# Posting to login form will result in 404
response = client.post(
reverse("login"), data={"username": "test", "password": "test"}
reverse("account_login"), data={"username": "test", "password": "test"}
)
assert "Not Found" in response.content.decode()

Expand All @@ -126,7 +127,7 @@ def test_google_login_setting(client, new_hire_factory, integration_factory):
org = Organization.object.get()
org.google_login = True
org.save()
response = client.get(reverse("login"))
response = client.get(reverse("account_login"))

# Login form should be here
assert "Log in with Google" in response.content.decode()
Expand All @@ -136,7 +137,7 @@ def test_google_login_setting(client, new_hire_factory, integration_factory):
org.save()

# Login form should be gone
response = client.get(reverse("login"))
response = client.get(reverse("account_login"))
assert "Log in with Google" not in response.content.decode()


Expand All @@ -148,7 +149,7 @@ def test_oidc_login_setting(client, new_hire_factory, settings):
org = Organization.object.get()
org.oidc_login = True
org.save()
response = client.get(reverse("login"))
response = client.get(reverse("account_login"))
# make sure the login form is there
settings.OIDC_FORCE_AUTHN = False
# Login form should be here
Expand All @@ -160,101 +161,18 @@ def test_oidc_login_setting(client, new_hire_factory, settings):
org.save()

# Login form should be gone
response = client.get(reverse("login"))
response = client.get(reverse("account_login"))
assert login_name not in response.content.decode()


@pytest.mark.django_db
@patch("pyotp.TOTP.verify", Mock(return_value=False))
def test_MFA_setting_with_valid_totp(client, new_hire_factory):
# Start with credentials enabled
new_hire = new_hire_factory(requires_otp=True)
new_hire.set_password("strong_pass")
new_hire.save()

response = client.post(
reverse("login"),
data={"username": new_hire.email, "password": "strong_pass"},
follow=True,
)

user = auth.get_user(client)
# User is logged in, but will fail any user test because of MFA not verified
assert user.is_authenticated
# User will be redirect to MFA form
assert "/mfa/?next=/redirect/" in response.redirect_chain[-1][0]

# Test going to a random page
response = client.post(reverse("new_hire:colleagues"), follow=True)
# User will be redirect to MFA form again
assert "/mfa/?next=/new_hire/colleagues/" in response.redirect_chain[-1][0]

# Enter invalid MFA token and redirect back
response = client.post(reverse("mfa"), {"otp": 223456})
assert "OTP token was not correct." in response.content.decode()
assert "Colleagues" not in response.content.decode()


@pytest.mark.django_db
@patch("pyotp.TOTP.verify", Mock(return_value=False))
def test_MFA_setting_with_recovery_key(client, new_hire_factory):
new_hire = new_hire_factory(requires_otp=True)
new_hire.set_password("strong_pass")
new_hire.save()

# Reset OTP keys so we have fresh ones
otp_keys = new_hire.reset_otp_recovery_keys()

response = client.post(
reverse("login"),
data={"username": new_hire.email, "password": "strong_pass"},
follow=True,
)

# Enter invalid MFA token and redirect back
response = client.post(reverse("mfa"), {"otp": 223456}, follow=True)
assert "OTP token was not correct." in response.content.decode()

# Test with recovery key instead
response = client.post(reverse("mfa"), {"otp": otp_keys[0]}, follow=True)
assert "OTP token was not correct." not in response.content.decode()
assert "Colleagues" in response.content.decode()

new_hire.refresh_from_db()

assert not new_hire.requires_otp


@pytest.mark.django_db
@patch("pyotp.TOTP.verify", Mock(return_value=True))
def test_MFA_setting_with_invalid_totp(client, new_hire_factory):
# Start with credentials enabled
new_hire = new_hire_factory(requires_otp=True)
new_hire.set_password("strong_pass")
new_hire.save()

response = client.post(
reverse("login"),
data={"username": new_hire.email, "password": "strong_pass"},
follow=True,
)

# Enter valid (faked) MFA token
response = client.post(reverse("mfa"), {"otp": 123456}, follow=True)

assert "/new_hire/todos/" in response.redirect_chain[-1][0]

# Random url to check if MFA persists
response = client.get(reverse("new_hire:colleagues"), follow=True)
assert "Colleagues" in response.content.decode()


@pytest.mark.django_db
@pytest.mark.parametrize("url", get_all_urls())
def test_authed_view(url, client, new_hire_factory):
# This test is only here to check that we aren't accidentally exposing any urls to
# the public (without authentication)
new_hire = new_hire_factory(requires_otp=True)
new_hire = new_hire_factory()
# also add mfa
Authenticator(user=new_hire, type=Authenticator.Type.TOTP)
new_hire.set_password("strong_pass")
new_hire.save()

Expand Down Expand Up @@ -298,7 +216,7 @@ def test_authed_view(url, client, new_hire_factory):
)

# Make sure the url also has MFA enabled
url = reverse("login")
url = reverse("account_login")
data = {"username": new_hire.email, "password": "strong_pass"}
response = client.post(url, data, follow=True)
assert "/mfa/" in response.redirect_chain[-1][0]
Expand Down
10 changes: 5 additions & 5 deletions back/user_auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def get(self, request):
request,
_("Something went wrong with reaching Google. Please try again."),
)
return redirect("login")
return redirect("account_login")
if "email" in user_info:
users = get_user_model().objects.filter(email=user_info["email"])
if users.exists():
Expand All @@ -134,7 +134,7 @@ def get(self, request):
" log in with the correct account?"
),
)
return redirect("login")
return redirect("account_login")


class OIDCLoginView(View):
Expand All @@ -153,7 +153,7 @@ def dispatch(self, request, *args, **kwargs):
self.request,
_("OIDC login has not been enabled."),
)
return redirect("login")
return redirect("account_login")
# Make sure these configd exists. Technically, it shouldn't be possible
# to enable `oidc_login` when this is not set, but just to be safe
OIDC_CLIENT_ID_VALID = settings.OIDC_CLIENT_ID.strip() != ""
Expand Down Expand Up @@ -211,7 +211,7 @@ def handle_callback(self, request, authorization_code):
" log in with the correct account?"
),
)
return redirect("login")
return redirect("account_login")

login(request, user)
# add login type to session, so we can redirect to the correct page when we
Expand All @@ -228,7 +228,7 @@ def handle_callback(self, request, authorization_code):
request,
_("Something went wrong with reaching OIDC. Please try again."),
)
return redirect("login")
return redirect("account_login")

def request_tokens(self, authorization_code):
data = {
Expand Down
1 change: 0 additions & 1 deletion back/users/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ def test_name(first_name, last_name, initials, full_name, new_hire_factory):
def test_unique_user_props(new_hire_factory):
user1 = new_hire_factory()
user2 = new_hire_factory()
assert user1.totp_secret != user2.totp_secret
assert user1.unique_url != user2.unique_url


Expand Down

0 comments on commit 2dbb59c

Please sign in to comment.