Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
benjackwhite committed Dec 13, 2024
1 parent b396947 commit c0893d0
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 22 deletions.
41 changes: 21 additions & 20 deletions posthog/api/test/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def test_notifications_sent_when_user_email_is_changed_and_email_available(
token = email_verification_token_generator.make_token(self.user)
with freeze_time("2020-01-01T21:37:00+00:00"):
response = self.client.post(
f"/api/users/@me/verify_email/",
f"/api/users/verify_email/",
{"uuid": self.user.uuid, "token": token},
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
Expand Down Expand Up @@ -1068,7 +1068,7 @@ def setUp(self):
def test_user_can_request_verification_email(self, mock_capture):
set_instance_setting("EMAIL_HOST", "localhost")
with self.settings(CELERY_TASK_ALWAYS_EAGER=True, SITE_URL="https://my.posthog.net"):
response = self.client.post(f"/api/users/@me/request_email_verification/", {"uuid": self.user.uuid})
response = self.client.post(f"/api/users/request_email_verification/", {"uuid": self.user.uuid})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.content.decode(), '{"success":true}')
self.assertSetEqual({",".join(outmail.to) for outmail in mail.outbox}, {self.CONFIG_EMAIL})
Expand All @@ -1086,7 +1086,7 @@ def test_user_can_request_verification_email(self, mock_capture):
reset_link = html_message[link_index : html_message.find('"', link_index)]
token = reset_link.replace("https://my.posthog.net/verify_email/", "").replace(f"{self.user.uuid}/", "")

response = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid, "token": token})
response = self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid, "token": token})
self.assertEqual(response.status_code, status.HTTP_200_OK)

# check is_email_verified is changed to True
Expand Down Expand Up @@ -1120,8 +1120,9 @@ def test_user_can_request_verification_email(self, mock_capture):
self.assertEqual(mock_capture.call_count, 3)

def test_cant_verify_if_email_is_not_configured(self):
set_instance_setting("EMAIL_HOST", "")
with self.settings(CELERY_TASK_ALWAYS_EAGER=True):
response = self.client.post(f"/api/users/@me/request_email_verification/", {"uuid": self.user.uuid})
response = self.client.post(f"/api/users/request_email_verification/", {"uuid": self.user.uuid})
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
response.json(),
Expand All @@ -1139,7 +1140,7 @@ def test_cant_verify_more_than_six_times(self):
for i in range(7):
with self.settings(CELERY_TASK_ALWAYS_EAGER=True, SITE_URL="https://my.posthog.net"):
response = self.client.post(
f"/api/users/@me/request_email_verification/",
f"/api/users/request_email_verification/",
{"uuid": self.user.uuid},
)
if i < 6:
Expand All @@ -1159,11 +1160,11 @@ def test_cant_verify_more_than_six_times(self):

def test_can_validate_email_verification_token(self):
token = email_verification_token_generator.make_token(self.user)
response = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid, "token": token})
response = self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid, "token": token})
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_cant_validate_email_verification_token_without_a_token(self):
response = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid})
response = self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid})
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
response.json(),
Expand All @@ -1189,7 +1190,7 @@ def test_invalid_verification_token_returns_error(self):
expired_token,
]:
response = self.client.post(
f"/api/users/@me/verify_email/",
f"/api/users/verify_email/",
{"uuid": self.user.uuid, "token": token},
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
Expand All @@ -1205,10 +1206,10 @@ def test_invalid_verification_token_returns_error(self):

def test_can_only_validate_email_token_one_time(self):
token = email_verification_token_generator.make_token(self.user)
response = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid, "token": token})
response = self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid, "token": token})
self.assertEqual(response.status_code, status.HTTP_200_OK)

response = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid, "token": token})
response = self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid, "token": token})
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
response.json(),
Expand All @@ -1229,7 +1230,7 @@ def test_email_verification_logs_in_user(self):
assert session_user_id is None

# NOTE: Posting sets the session user id but doesn't log in the test client hence we just check the session id
self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid, "token": token})
self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid, "token": token})
session_user_id = self.client.session.get("_auth_user_id")
assert session_user_id == str(self.user.id)

Expand All @@ -1239,16 +1240,14 @@ def test_email_verification_logs_in_correctuser(self):
assert self.client.session.get("_auth_user_id") is None

# NOTE: The user id in path should basically be ignored
self.client.post(
f"/api/users/{self.user.uuid}/verify_email/", {"uuid": self.other_user.uuid, "token": other_token}
)
self.client.post(f"/api/users/verify_email/", {"uuid": self.other_user.uuid, "token": other_token})
session_user_id = self.client.session.get("_auth_user_id")
assert session_user_id == str(self.other_user.id)

def test_email_verification_does_not_apply_to_current_logged_in_user(self):
other_token = email_verification_token_generator.make_token(self.other_user)

res = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.other_user.uuid, "token": other_token})
res = self.client.post(f"/api/users/verify_email/", {"uuid": self.other_user.uuid, "token": other_token})
assert res.status_code == status.HTTP_200_OK
self.user.refresh_from_db()
self.other_user.refresh_from_db()
Expand All @@ -1263,18 +1262,20 @@ def test_email_verification_fails_if_using_other_accounts_token(self):
self.client.logout()

options_to_test = [
# Same user IDs with the wrong token
[self.user.uuid, self.user.uuid, other_token],
[self.other_user.uuid, self.user.uuid, other_token],
[self.user.uuid, self.other_user.uuid, token],
[self.other_user.uuid, self.other_user.uuid, token],
# Check we use it from the path
[self.other_user.uuid, self.user.uuid, token],
[self.user.uuid, self.other_user.uuid, other_token],
["@me", self.other_user.uuid, other_token],
]

for user_uuid, path_user_uuid, token in options_to_test:
print("Testing", user_uuid, path_user_uuid, token) # noqa
response = self.client.post(
f"/api/users/{path_user_uuid}/verify_email/", {"uuid": user_uuid, "token": token}
)
print(self.other_user.id, self.user.id, self.client.session.get("_auth_user_id"))
assert response.status_code == status.HTTP_400_BAD_REQUEST

def test_does_not_apply_pending_email_for_old_tokens(self):
Expand All @@ -1284,13 +1285,13 @@ def test_does_not_apply_pending_email_for_old_tokens(self):
self.user.pending_email = "[email protected]"
self.user.save()

response = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid, "token": token})
response = self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid, "token": token})
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert self.user.email != "[email protected]"
assert self.user.pending_email == "[email protected]"

token = email_verification_token_generator.make_token(self.user)
response = self.client.post(f"/api/users/@me/verify_email/", {"uuid": self.user.uuid, "token": token})
response = self.client.post(f"/api/users/verify_email/", {"uuid": self.user.uuid, "token": token})
assert response.status_code == status.HTTP_200_OK
self.user.refresh_from_db()
assert self.user.email == "[email protected]"
Expand Down
4 changes: 2 additions & 2 deletions posthog/api/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def get_serializer_context(self):
"user_permissions": UserPermissions(cast(User, self.request.user)),
}

@action(methods=["POST"], detail=True, permission_classes=[AllowAny])
@action(methods=["POST"], detail=False, permission_classes=[AllowAny])
def verify_email(self, request, **kwargs):
token = request.data["token"] if "token" in request.data else None
user_uuid = request.data["uuid"]
Expand Down Expand Up @@ -422,7 +422,7 @@ def verify_email(self, request, **kwargs):

@action(
methods=["POST"],
detail=True,
detail=False,
permission_classes=[AllowAny],
throttle_classes=[UserEmailVerificationThrottle],
)
Expand Down

0 comments on commit c0893d0

Please sign in to comment.