Skip to content
Merged
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
6 changes: 3 additions & 3 deletions common/djangoapps/student/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
COURSE_ENROLLMENT_CREATED,
COURSE_UNENROLLMENT_COMPLETED,
)
from openedx_filters.learning.enrollment import PreEnrollmentFilter
from openedx_filters.learning.filters import CourseEnrollmentStarted
import openedx.core.djangoapps.django_comment_common.comment_client as cc
from common.djangoapps.course_modes.models import CourseMode, get_cosmetic_verified_display_price
from common.djangoapps.student.emails import send_proctoring_requirements_email
Expand Down Expand Up @@ -1620,10 +1620,10 @@ def enroll(cls, user, course_key, mode=None, check_access=False, can_upgrade=Fal
Also emits relevant events for analytics purposes.
"""
try:
user, course_key, mode = PreEnrollmentFilter.run(
user, course_key, mode = CourseEnrollmentStarted.run_filter(
user=user, course_key=course_key, mode=mode,
)
except PreEnrollmentFilter.PreventEnrollment as exc:
except CourseEnrollmentStarted.PreventEnrollment as exc:
raise EnrollmentNotAllowed(str(exc)) from exc

if mode is None:
Expand Down
32 changes: 22 additions & 10 deletions common/djangoapps/student/tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,25 @@
Test that various filters are fired for models in the student app.
"""
from django.test import override_settings
from openedx_filters.learning.enrollment import PreEnrollmentFilter
from openedx_filters import PipelineStep
from openedx_filters.learning.filters import CourseEnrollmentStarted
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory

from common.djangoapps.student.models import CourseEnrollment, EnrollmentNotAllowed
from common.djangoapps.student.tests.factories import UserFactory, UserProfileFactory

from openedx.core.djangolib.testing.utils import skip_unless_lms

from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory


class TestEnrollmentPipelineStep(PipelineStep):
"""
Utility function used when getting steps for pipeline.
"""

def run(self, user, course_key, mode): # pylint: disable=unused-argument, arguments-differ
def run_filter(self, user, course_key, mode): # pylint: disable=arguments-differ, unused-argument
"""Pipeline steps that changes mode to honor."""
if mode == "no-id-professional":
raise PreEnrollmentFilter.PreventEnrollment()
raise CourseEnrollmentStarted.PreventEnrollment()
return {"mode": "honor"}


Expand All @@ -33,7 +31,7 @@ class EnrollmentFiltersTest(ModuleStoreTestCase):

This class guarantees that the following filters are triggered during the user's enrollment:

- PreEnrollmentFilter
- CourseEnrollmentStarted
"""

def setUp(self): # pylint: disable=arguments-differ
Expand Down Expand Up @@ -62,7 +60,7 @@ def test_enrollment_filter_executed(self):
enrollment process.

Expected result:
- PreEnrollmentFilter is triggered and executes TestEnrollmentPipelineStep.
- CourseEnrollmentStarted is triggered and executes TestEnrollmentPipelineStep.
- The arguments that the receiver gets are the arguments used by the filter
with the enrollment mode changed.
"""
Expand All @@ -85,8 +83,22 @@ def test_enrollment_filter_prevent_enroll(self):
Test prevent the user's enrollment through a pipeline step.

Expected result:
- PreEnrollmentFilter is triggered and executes TestEnrollmentPipelineStep.
- CourseEnrollmentStarted is triggered and executes TestEnrollmentPipelineStep.
- The user can't enroll.
"""
with self.assertRaises(EnrollmentNotAllowed):
CourseEnrollment.enroll(self.user, self.course.id, mode='no-id-professional')

@override_settings(OPEN_EDX_FILTERS_CONFIG={})
def test_enrollment_without_filter_configuration(self):
"""
Test usual enrollment process, without filter's intervention.

Expected result:
- CourseEnrollmentStarted does not have any effect on the enrollment process.
- The enrollment process ends successfully.
"""
enrollment = CourseEnrollment.enroll(self.user, self.course.id, mode='audit')

self.assertEqual('audit', enrollment.mode)
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
12 changes: 12 additions & 0 deletions openedx/core/djangoapps/user_authn/views/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

from openedx_events.learning.data import UserData, UserPersonalData
from openedx_events.learning.signals import SESSION_LOGIN_COMPLETED
from openedx_filters.learning.filters import StudentLoginRequested

from common.djangoapps.edxmako.shortcuts import render_to_response
from openedx.core.djangoapps.password_policy import compliance as password_policy_compliance
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
Expand Down Expand Up @@ -515,6 +517,16 @@ def login_user(request):

possibly_authenticated_user = user

try:
possibly_authenticated_user = StudentLoginRequested.run_filter(user=possibly_authenticated_user)
except StudentLoginRequested.PreventLogin as exc:
raise AuthFailedError(
str(exc),
redirect_url=exc.redirect_to, # pylint: disable=no-member
error_code=exc.error_code, # pylint: disable=no-member
context=exc.context, # pylint: disable=no-member
) from exc

if not is_user_third_party_authenticated:
possibly_authenticated_user = _authenticate_first_party(request, user, third_party_auth_requested)
if possibly_authenticated_user and password_policy_compliance.should_enforce_compliance_on_login():
Expand Down
9 changes: 9 additions & 0 deletions openedx/core/djangoapps/user_authn/views/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace
from openedx_events.learning.data import UserData, UserPersonalData
from openedx_events.learning.signals import STUDENT_REGISTRATION_COMPLETED
from openedx_filters.learning.filters import StudentRegistrationRequested
from pytz import UTC
from ratelimit.decorators import ratelimit
from requests import HTTPError
Expand Down Expand Up @@ -536,6 +537,14 @@ def post(self, request):
data = request.POST.copy()
self._handle_terms_of_service(data)

try:
data = StudentRegistrationRequested.run_filter(form_data=data)
except StudentRegistrationRequested.PreventRegistration as exc:
errors = {
"error_message": [{"user_message": str(exc)}],
}
return self._create_response(request, errors, status_code=exc.status_code)

response = self._handle_duplicate_email_username(request, data)
if response:
return response
Expand Down
Loading