Skip to content

Commit f40db10

Browse files
ihalaij1markkuriekkinen
authored andcommitted
Protect against buggy participants reports from Aalto SISU API
Fixes apluslms#1180
1 parent b8e9c05 commit f40db10

File tree

1 file changed

+23
-14
lines changed

1 file changed

+23
-14
lines changed

course/models.py

+23-14
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from django.utils.text import format_lazy
2121
from django.utils.translation import gettext_lazy as _
2222
from django_colortag.models import ColorTag
23+
from requests.exceptions import HTTPError
2324

2425
from apps.models import BaseTab, BasePlugin
2526
from authorization.models import JWTAccessible
@@ -925,8 +926,11 @@ def enroll_from_sis(self) -> Tuple[int, int]:
925926
delcount = 0
926927
try:
927928
participants = sis.get_participants(self.sis_id)
928-
except Exception as e:
929-
logger.exception(f"{self}: Error in getting participants from SIS.")
929+
except HTTPError as exc:
930+
logger.exception("%s: Error %d when getting participants from SIS.", self, exc.response.status_code)
931+
return -1, -1
932+
except Exception:
933+
logger.exception("%s: Error in getting participants from SIS.", self)
930934
return -1, -1
931935

932936
from exercise.models import LearningObject
@@ -943,18 +947,23 @@ def enroll_from_sis(self) -> Tuple[int, int]:
943947
# yet logged in to A+, then the user profile does not exist yet.
944948
pass
945949

946-
# Remove SIS-enrolled students who are not anymore in SIS participants,
947-
# for example, because they have first enrolled in SIS, but then
948-
# unenrolled themselves.
949-
students = self.all_students.filter(enrollment__from_sis=True)
950-
to_remove = students.exclude(student_id__in=participants)
951-
qs = Enrollment.objects.filter(user_profile__in=to_remove, course_instance=self)
952-
qs.update(status=Enrollment.ENROLLMENT_STATUS.REMOVED)
953-
for e in qs:
954-
invalidate_content(Enrollment, e)
955-
delcount += 1
956-
957-
logger.info(f"{self}: enrolled {addcount}, removed {delcount} students based on SIS")
950+
# Ignore empty participants list caused by a rare SIS API gateway malfunction
951+
if participants:
952+
# Remove SIS-enrolled students who are not anymore in SIS participants,
953+
# for example, because they have first enrolled in SIS, but then
954+
# unenrolled themselves.
955+
students = self.all_students.filter(enrollment__from_sis=True)
956+
to_remove = students.exclude(student_id__in=participants)
957+
qs = Enrollment.objects.filter(user_profile__in=to_remove, course_instance=self)
958+
qs.update(status=Enrollment.ENROLLMENT_STATUS.REMOVED)
959+
for e in qs:
960+
invalidate_content(Enrollment, e)
961+
delcount += 1
962+
else:
963+
logger.warning("%s: Received an empty participants list from SIS.", self)
964+
return 0, 0
965+
966+
logger.info("%s: enrolled %d, removed %d students based on SIS", self, addcount, delcount)
958967
return addcount, delcount
959968

960969
def set_users_with_role(self, users, role, remove_others_with_role=False):

0 commit comments

Comments
 (0)