def password_change_request_handler(request): """Handle password change requests originating from the account page. Uses the Account API to email the user a link to the password reset page. Note: The next step in the password reset process (confirmation) is currently handled by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's password reset confirmation view. Args: request (HttpRequest) Returns: HttpResponse: 200 if the email was sent successfully HttpResponse: 400 if there is no 'email' POST parameter HttpResponse: 403 if the client has been rate limited HttpResponse: 405 if using an unsupported HTTP method Example usage: POST /account/password """ limiter = BadRequestRateLimiter() if limiter.is_rate_limit_exceeded(request): AUDIT_LOG.warning("Password reset rate limit exceeded") return HttpResponseForbidden() user = request.user # Prefer logged-in user's email email = user.email if user.is_authenticated() else request.POST.get( 'email') if email: try: request_password_change(email, request.is_secure()) user = user if user.is_authenticated() else User.objects.get( email=email) destroy_oauth_tokens(user) except UserNotFound: AUDIT_LOG.info("Invalid password reset attempt") # Increment the rate limit counter limiter.tick_bad_request_counter(request) except UserAPIInternalError as err: log.exception( 'Error occured during password change for user {email}: {error}' .format(email=email, error=err)) return HttpResponse(_( "Some error occured during password change. Please try again"), status=500) return HttpResponse(status=200) else: return HttpResponseBadRequest(_("No email address provided."))
def password_change_request_handler(request): """Handle password change requests originating from the account page. Uses the Account API to email the user a link to the password reset page. Note: The next step in the password reset process (confirmation) is currently handled by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's password reset confirmation view. Args: request (HttpRequest) Returns: HttpResponse: 200 if the email was sent successfully HttpResponse: 400 if there is no 'email' POST parameter HttpResponse: 403 if the client has been rate limited HttpResponse: 405 if using an unsupported HTTP method Example usage: POST /account/password """ limiter = BadRequestRateLimiter() if limiter.is_rate_limit_exceeded(request): AUDIT_LOG.warning("Password reset rate limit exceeded") return HttpResponseForbidden() user = request.user # Prefer logged-in user's email email = user.email if user.is_authenticated() else request.POST.get('email') if email: try: request_password_change(email, request.is_secure()) user = user if user.is_authenticated() else User.objects.get(email=email) destroy_oauth_tokens(user) except UserNotFound: AUDIT_LOG.info("Invalid password reset attempt") # Increment the rate limit counter limiter.tick_bad_request_counter(request) except UserAPIInternalError as err: log.exception('Error occured during password change for user {email}: {error}' .format(email=email, error=err)) return HttpResponse(_("Some error occured during password change. Please try again"), status=500) return HttpResponse(status=200) else: return HttpResponseBadRequest(_("No email address provided."))
def post(self, request, format=None): data = request.data if 'email' in data: limiter = BadRequestRateLimiter() if limiter.is_rate_limit_exceeded(request): AUDIT_LOG.warning("Password reset rate limit exceeded") return HttpResponseForbidden() email = data['email'] if len(email) > 0: try: request_password_change(email, request.get_host(), request.is_secure()) user = User.objects.get(email=email) destroy_oauth_tokens(user) return Response( { "message": "You will receive your new password on your email." }, status=status.HTTP_200_OK) except UserNotFound: AUDIT_LOG.info("Invalid password reset attempt") # Increment the rate limit counter limiter.tick_bad_request_counter(request) return Response({"error": "Provide a valid email."}, status=status.HTTP_400_BAD_REQUEST) else: return Response( {"error": "Provide an email to recover your password."}, status=status.HTTP_400_BAD_REQUEST) else: return Response( {"error": "Provide an email to recover your password."}, status=status.HTTP_400_BAD_REQUEST)
def password_change_request_handler(request): """Handle password change requests originating from the account page. Uses the Account API to email the user a link to the password reset page. Note: The next step in the password reset process (confirmation) is currently handled by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's password reset confirmation view. Args: request (HttpRequest) Returns: HttpResponse: 200 if the email was sent successfully HttpResponse: 400 if there is no 'email' POST parameter HttpResponse: 403 if the client has been rate limited HttpResponse: 405 if using an unsupported HTTP method Example usage: POST /account/password """ limiter = BadRequestRateLimiter() if limiter.is_rate_limit_exceeded(request): AUDIT_LOG.warning("Password reset rate limit exceeded") return HttpResponseForbidden() user = request.user # Prefer logged-in user's email email = user.email if user.is_authenticated else request.POST.get('email') if email: try: request_password_change(email, request.is_secure()) user = user if user.is_authenticated else User.objects.get( email=email) destroy_oauth_tokens(user) except UserNotFound: AUDIT_LOG.info("Invalid password reset attempt") # Increment the rate limit counter limiter.tick_bad_request_counter(request) # If enabled, send an email saying that a password reset was attempted, but that there is # no user associated with the email if configuration_helpers.get_value( 'ENABLE_PASSWORD_RESET_FAILURE_EMAIL', settings.FEATURES['ENABLE_PASSWORD_RESET_FAILURE_EMAIL']): site = Site.objects.get_current() message_context = get_base_template_context(site) message_context.update({ 'failed': True, 'request': request, # Used by google_analytics_tracking_pixel 'email_address': email, }) msg = PasswordReset().personalize( recipient=Recipient(username='', email_address=email), language=settings.LANGUAGE_CODE, user_context=message_context, ) ace.send(msg) except UserAPIInternalError as err: log.exception( 'Error occured during password change for user {email}: {error}' .format(email=email, error=err)) return HttpResponse(_( "Some error occured during password change. Please try again"), status=500) return HttpResponse(status=200) else: return HttpResponseBadRequest(_("No email address provided."))
def password_change_request_handler(request): """Handle password change requests originating from the account page. Uses the Account API to email the user a link to the password reset page. Note: The next step in the password reset process (confirmation) is currently handled by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's password reset confirmation view. Args: request (HttpRequest) Returns: HttpResponse: 200 if the email was sent successfully HttpResponse: 400 if there is no 'email' POST parameter HttpResponse: 403 if the client has been rate limited HttpResponse: 405 if using an unsupported HTTP method Example usage: POST /account/password """ limiter = BadRequestRateLimiter() if limiter.is_rate_limit_exceeded(request): AUDIT_LOG.warning("Password reset rate limit exceeded") return HttpResponseForbidden() user = request.user # Prefer logged-in user's email email = user.email if user.is_authenticated else request.POST.get('email') if email: try: request_password_change(email, request.is_secure()) user = user if user.is_authenticated else User.objects.get(email=email) destroy_oauth_tokens(user) except UserNotFound: AUDIT_LOG.info("Invalid password reset attempt") # Increment the rate limit counter limiter.tick_bad_request_counter(request) # If enabled, send an email saying that a password reset was attempted, but that there is # no user associated with the email if configuration_helpers.get_value('ENABLE_PASSWORD_RESET_FAILURE_EMAIL', settings.FEATURES['ENABLE_PASSWORD_RESET_FAILURE_EMAIL']): site = get_current_site() message_context = get_base_template_context(site) message_context.update({ 'failed': True, 'request': request, # Used by google_analytics_tracking_pixel 'email_address': email, }) msg = PasswordReset().personalize( recipient=Recipient(username='', email_address=email), language=settings.LANGUAGE_CODE, user_context=message_context, ) ace.send(msg) except UserAPIInternalError as err: log.exception('Error occured during password change for user {email}: {error}' .format(email=email, error=err)) return HttpResponse(_("Some error occured during password change. Please try again"), status=500) return HttpResponse(status=200) else: return HttpResponseBadRequest(_("No email address provided."))
def password_change_request_handler(request): """Handle password change requests originating from the account page. Uses the Account API to email the user a link to the password reset page. Note: The next step in the password reset process (confirmation) is currently handled by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's password reset confirmation view. Args: request (HttpRequest) Returns: HttpResponse: 200 if the email was sent successfully HttpResponse: 400 if there is no 'email' POST parameter HttpResponse: 403 if the client has been rate limited HttpResponse: 405 if using an unsupported HTTP method Example usage: POST /account/password """ limiter = BadRequestRateLimiter() if limiter.is_rate_limit_exceeded(request): AUDIT_LOG.warning("Password reset rate limit exceeded") return HttpResponseForbidden() user = request.user # Prefer logged-in user's email email = user.email if user.is_authenticated() else request.POST.get('email') if email: try: request_password_change(email, request.is_secure()) user = user if user.is_authenticated() else User.objects.get(email=email) destroy_oauth_tokens(user) except UserNotFound: AUDIT_LOG.info("Invalid password reset attempt") # Increment the rate limit counter limiter.tick_bad_request_counter(request) # If enabled, send an email saying that a password reset was attempted, but that there is # no user associated with the email if configuration_helpers.get_value('ENABLE_PASSWORD_RESET_FAILURE_EMAIL', settings.FEATURES['ENABLE_PASSWORD_RESET_FAILURE_EMAIL']): context = { 'failed': True, 'email_address': email, 'platform_name': configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME), } subject = loader.render_to_string('emails/password_reset_subject.txt', context) subject = ''.join(subject.splitlines()) message = loader.render_to_string('registration/password_reset_email.html', context) from_email = configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL) try: send_mail(subject, message, from_email, [email], html_message=message) except Exception: # pylint: disable=broad-except log.exception(u'Unable to send password reset failure email notification from "%s"', from_email) except UserAPIInternalError as err: log.exception('Error occured during password change for user {email}: {error}' .format(email=email, error=err)) return HttpResponse(_("Some error occured during password change. Please try again"), status=500) return HttpResponse(status=200) else: return HttpResponseBadRequest(_("No email address provided."))
def password_change_request_handler(request): """Handle password change requests originating from the account page. Uses the Account API to email the user a link to the password reset page. Note: The next step in the password reset process (confirmation) is currently handled by student.views.password_reset_confirm_wrapper, a custom wrapper around Django's password reset confirmation view. Args: request (HttpRequest) Returns: HttpResponse: 200 if the email was sent successfully HttpResponse: 400 if there is no 'email' POST parameter HttpResponse: 403 if the client has been rate limited HttpResponse: 405 if using an unsupported HTTP method Example usage: POST /account/password """ limiter = BadRequestRateLimiter() if limiter.is_rate_limit_exceeded(request): AUDIT_LOG.warning("Password reset rate limit exceeded") return HttpResponseForbidden() user = request.user # Prefer logged-in user's email email = user.email if user.is_authenticated() else request.POST.get('email') if email: try: request_password_change(email, request.is_secure()) user = user if user.is_authenticated() else User.objects.get(email=email) destroy_oauth_tokens(user) except UserNotFound: AUDIT_LOG.info("Invalid password reset attempt") # Increment the rate limit counter limiter.tick_bad_request_counter(request) # If enabled, send an email saying that a password reset was attempted, but that there is # no user associated with the email if configuration_helpers.get_value('ENABLE_PASSWORD_RESET_FAILURE_EMAIL', settings.FEATURES['ENABLE_PASSWORD_RESET_FAILURE_EMAIL']): context = { 'failed': True, 'email_address': email, 'platform_name': configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME), } subject = loader.render_to_string('emails/password_reset_subject.txt', context) subject = ''.join(subject.splitlines()) message = loader.render_to_string('registration/password_reset_email.html', context) from_email = configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL) try: send_mail(subject, message, from_email, [email]) except Exception: # pylint: disable=broad-except log.exception(u'Unable to send password reset failure email notification from "%s"', from_email) except UserAPIInternalError as err: log.exception('Error occured during password change for user {email}: {error}' .format(email=email, error=err)) return HttpResponse(_("Some error occured during password change. Please try again"), status=500) return HttpResponse(status=200) else: return HttpResponseBadRequest(_("No email address provided."))