From eaa46dc43e6da2ad7e5da5d7a1db4b90ea2f9756 Mon Sep 17 00:00:00 2001 From: Sher Ali Date: Thu, 11 Mar 2021 12:44:32 +0500 Subject: [PATCH 1/2] stop user from going to /courses after auth --- common/djangoapps/student/helpers.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/djangoapps/student/helpers.py b/common/djangoapps/student/helpers.py index 8115bfc54018..524e67df8cb3 100644 --- a/common/djangoapps/student/helpers.py +++ b/common/djangoapps/student/helpers.py @@ -275,7 +275,11 @@ def get_next_url_for_login_page(request): If THIRD_PARTY_AUTH_HINT is set, then `tpa_hint=` is added as a query parameter. """ redirect_to = _get_redirect_to(request) - if not redirect_to: + # [UCSD_CUSTOM] stop user from going to /courses after login/registration/third_party_auth + if not redirect_to or (configuration_helpers.get_value( + 'ALWAYS_REDIRECT_HOMEPAGE_TO_COURSES_FOR_ANONYMOUS_USER', + settings.FEATURES.get('ALWAYS_REDIRECT_HOMEPAGE_TO_COURSES_FOR_ANONYMOUS_USER', False)) and + redirect_to == '/courses'): try: redirect_to = reverse('dashboard') except NoReverseMatch: From c8341d05ca1abeecd0ddc5bb7cf1e2efad183416 Mon Sep 17 00:00:00 2001 From: Sher Ali <49383675+sheralim012@users.noreply.github.com> Date: Wed, 17 Mar 2021 15:46:07 +0500 Subject: [PATCH 2/2] deactivate course enrollment when course overview is deleted (#453) * cascade delete course enrollment on course overview delete * fixed test case for course enrollment deletion * remove migraions and add signal to deactivate course enrollment --- openedx/features/ucsd_features/signals.py | 16 +++++++++++--- .../ucsd_features/tests/test_signals.py | 22 +++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/openedx/features/ucsd_features/signals.py b/openedx/features/ucsd_features/signals.py index ca24517e2ca0..bdba37ae45af 100644 --- a/openedx/features/ucsd_features/signals.py +++ b/openedx/features/ucsd_features/signals.py @@ -1,13 +1,14 @@ from logging import getLogger from django.conf import settings -from django.dispatch import receiver from django.db.models.signals import post_save, pre_save +from django.dispatch import receiver +from opaque_keys.edx.keys import CourseKey from lms.djangoapps.verify_student.models import ManualVerification from openedx.core.djangoapps.content.course_overviews.models import CourseOverview -from student.models import UserProfile - +from student.models import CourseEnrollment, UserProfile +from xmodule.modulestore.django import SignalHandler logger = getLogger(__name__) @@ -31,3 +32,12 @@ def generate_manual_verification_for_user(sender, instance, created, **kwargs): except Exception: # pylint: disable=broad-except logger.error('Error while generating ManualVerification for user: %s', instance.user.email, exc_info=True) + +@receiver(SignalHandler.course_deleted) +def _listen_for_course_delete(sender, course_key, **kwargs): # pylint: disable=unused-argument + """ + Catches the signal that a course has been deleted from Studio and + invalidates the corresponding CourseEnrollments if any exists. + """ + logger.info('Deactivate course enrollment for course_id: {}'.format(course_key)) + CourseEnrollment.objects.filter(course_id=course_key).update(is_active=False) diff --git a/openedx/features/ucsd_features/tests/test_signals.py b/openedx/features/ucsd_features/tests/test_signals.py index d41e81590753..d96fb5776bad 100644 --- a/openedx/features/ucsd_features/tests/test_signals.py +++ b/openedx/features/ucsd_features/tests/test_signals.py @@ -1,16 +1,22 @@ -import pytz from datetime import datetime +import pytz from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from django.test import TestCase from django.test.utils import override_settings from lms.djangoapps.verify_student.models import ManualVerification +from student.models import CourseEnrollment from student.tests.factories import UserFactory +from xmodule.modulestore.django import modulestore +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory + +class UCSDFeaturesSignalsTests(ModuleStoreTestCase): + ENABLED_SIGNALS = ['course_deleted'] -class UCSDFeaturesSignalsTests(TestCase): def test_user_is_verified_after_creation_when_flag_is_set(self): features = settings.FEATURES.copy() features['AUTOMATIC_PERMANENT_ACCOUNT_VERIFICATION'] = True @@ -36,3 +42,15 @@ def test_verification_attempt_expiration_datetime(self): verification_attempt = ManualVerification.objects.get(user=user) expected_expiration_datetime = datetime.max.replace(tzinfo=pytz.UTC) self.assertEqual(verification_attempt.expiration_datetime, expected_expiration_datetime) + + def test_deactivate_course_enrollment_on_course_delete(self): + user = UserFactory() + course = CourseFactory() + course_enrollment = CourseEnrollment.enroll(user, course.id) + module_store = modulestore() + + with module_store.bulk_operations(course.id): + module_store.delete_course(course.id, user.id) + + course_enrollment.refresh_from_db() + self.assertFalse(course_enrollment.is_active)