Skip to content

Commit

Permalink
feat: added tracking events for password reset initiation
Browse files Browse the repository at this point in the history
  • Loading branch information
sohailfatima committed Jun 4, 2024
2 parents bcf8b38 + 17f48ad commit 88339bc
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from django.utils.http import int_to_base36
from edx_ace import ace
from edx_ace.recipient import Recipient
from eventtracking import tracker

from common.djangoapps.student.models import AccountRecoveryConfiguration
from openedx.core.djangoapps.user_authn.toggles import should_redirect_to_authn_microfrontend
Expand All @@ -27,6 +28,7 @@
from openedx.core.lib.celery.task_utils import emulate_http_request

logger = logging.getLogger(__name__) # pylint: disable=invalid-name
PASSWORD_RESET_INITIATED = 'edx.user.passwordreset.initiated'


class Command(BaseCommand):
Expand Down Expand Up @@ -84,6 +86,13 @@ def handle(self, *args, **options):
user = get_user_model().objects.get(Q(username__iexact=username) | Q(email__iexact=current_email))
user.email = desired_email
user.save()
tracker.emit(
PASSWORD_RESET_INITIATED,
{
"user_id": user.id,
"source": "Account Recovery Management Command",
}
)
self.send_password_reset_email(user, site)
successful_updates.append(desired_email)
except Exception as exc: # pylint: disable=broad-except
Expand Down
9 changes: 9 additions & 0 deletions openedx/core/djangoapps/user_authn/views/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from django.views.decorators.http import require_http_methods
from django_ratelimit.decorators import ratelimit
from edx_django_utils.monitoring import set_custom_attribute
from eventtracking import tracker
from openedx_events.learning.data import UserData, UserPersonalData
from openedx_events.learning.signals import SESSION_LOGIN_COMPLETED
from openedx_filters.learning.filters import StudentLoginRequested
Expand Down Expand Up @@ -61,6 +62,7 @@
log = logging.getLogger("edx.student")
AUDIT_LOG = logging.getLogger("audit")
USER_MODEL = get_user_model()
PASSWORD_RESET_INITIATED = 'edx.user.passwordreset.initiated'


def _do_third_party_auth(request):
Expand Down Expand Up @@ -194,6 +196,13 @@ def _enforce_password_policy_compliance(request, user): # lint-amnesty, pylint:
LoginFailures.increment_lockout_counter(user)

AUDIT_LOG.info("Password reset initiated for email %s.", user.email)
tracker.emit(
PASSWORD_RESET_INITIATED,
{
"user_id": user.id,
"source": "Policy Compliance",
}
)
send_password_reset_email_for_user(user, request)

# Prevent the login attempt.
Expand Down
15 changes: 15 additions & 0 deletions openedx/core/djangoapps/user_authn/views/password_reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
POST_EMAIL_KEY = 'openedx.core.djangoapps.util.ratelimit.request_post_email'
REAL_IP_KEY = 'openedx.core.djangoapps.util.ratelimit.real_ip'
SETTING_CHANGE_INITIATED = 'edx.user.settings.change_initiated'
PASSWORD_RESET_INITIATED = 'edx.user.passwordreset.initiated'

# Maintaining this naming for backwards compatibility.
log = logging.getLogger("edx.student")
Expand Down Expand Up @@ -289,6 +290,13 @@ def password_reset(request):
user = request.user
# Prefer logged-in user's email
email = user.email if user.is_authenticated else request.POST.get('email')
tracker.emit(
PASSWORD_RESET_INITIATED,
{
"user_id": user.id,
"source": "Logistration Page",
}
)
AUDIT_LOG.info("Password reset initiated for email %s.", email)

if getattr(request, 'limited', False):
Expand Down Expand Up @@ -608,6 +616,13 @@ def password_change_request_handler(request):
# Prefer logged-in user's email
email = user.email if user.is_authenticated else request.POST.get('email')
AUDIT_LOG.info("Password reset initiated for email %s.", email)
tracker.emit(
PASSWORD_RESET_INITIATED,
{
"user_id": user.id,
"source": "Account API",
}
)

if getattr(request, 'limited', False) and not request_from_support_tools:
AUDIT_LOG.warning("Password reset rate limit exceeded for email %s.", email)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from openedx.core.djangoapps.user_api.tests.test_views import UserAPITestCase
from openedx.core.djangoapps.user_api.accounts import EMAIL_MAX_LENGTH, EMAIL_MIN_LENGTH
from openedx.core.djangoapps.user_authn.views.password_reset import (
SETTING_CHANGE_INITIATED, password_reset, LogistrationPasswordResetView,
SETTING_CHANGE_INITIATED, PASSWORD_RESET_INITIATED, password_reset, LogistrationPasswordResetView,
PasswordResetConfirmWrapper, password_change_request_handler)
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from common.djangoapps.student.tests.factories import TEST_PASSWORD, UserFactory
Expand Down Expand Up @@ -114,7 +114,7 @@ def test_user_bad_password_reset(self):
assert bad_pwd_resp.status_code == 200
obj = json.loads(bad_pwd_resp.content.decode('utf-8'))
assert obj == {'success': True, 'value': "('registration/password_reset_done.html', [])"}
self.assert_no_events_were_emitted()
self.assert_event_emission_count(PASSWORD_RESET_INITIATED, 1)

@patch(
'openedx.core.djangoapps.user_authn.views.password_reset.render_to_string',
Expand All @@ -134,7 +134,7 @@ def test_nonexist_email_password_reset(self):
assert bad_email_resp.status_code == 200
obj = json.loads(bad_email_resp.content.decode('utf-8'))
assert obj == {'success': True, 'value': "('registration/password_reset_done.html', [])"}
self.assert_no_events_were_emitted()
self.assert_event_emission_count(PASSWORD_RESET_INITIATED, 1)

@patch(
'openedx.core.djangoapps.user_authn.views.password_reset.render_to_string',
Expand All @@ -146,7 +146,6 @@ def test_password_reset_ratelimited_for_non_existing_user(self):
for non-existing user.
"""
self.assert_password_reset_ratelimitted('[email protected]', AnonymousUser())
self.assert_no_events_were_emitted()

@patch(
'openedx.core.djangoapps.user_authn.views.password_reset.render_to_string',
Expand Down

0 comments on commit 88339bc

Please sign in to comment.