diff --git a/dmoj/settings.py b/dmoj/settings.py index 8f9fd7058..11895be7a 100755 --- a/dmoj/settings.py +++ b/dmoj/settings.py @@ -100,6 +100,10 @@ VNOJ_TAG_PROBLEM_MIN_RATING = 1900 # Minimum rating to be able to tag a problem +VNOJ_SHOULD_BAN_FOR_CHEATING_IN_CONTESTS = False +VNOJ_CONTEST_CHEATING_BAN_MESSAGE = 'Banned for multiple cheating offenses during contests' +VNOJ_MAX_DISQUALIFICATIONS_BEFORE_BANNING = 3 + # List of subdomain that will be ignored in organization subdomain middleware VNOJ_IGNORED_ORGANIZATION_SUBDOMAINS = ['oj', 'www', 'localhost'] diff --git a/judge/models/contest.py b/judge/models/contest.py index 45e58d308..a311e5681 100644 --- a/judge/models/contest.py +++ b/judge/models/contest.py @@ -589,6 +589,23 @@ def recompute_results(self): self.save(update_fields=['score', 'cumtime', 'tiebreaker']) recompute_results.alters_data = True + def check_ban(self): + if not settings.VNOJ_SHOULD_BAN_FOR_CHEATING_IN_CONTESTS or self.contest.is_organization_private: + return + + disqualifications_count = ContestParticipation.objects.filter( + user=self.user, + contest__is_organization_private=False, + is_disqualified=True, + ).count() + if disqualifications_count >= settings.VNOJ_MAX_DISQUALIFICATIONS_BEFORE_BANNING and \ + not self.user.is_banned: + self.user.ban_user(settings.VNOJ_CONTEST_CHEATING_BAN_MESSAGE) + elif disqualifications_count < settings.VNOJ_MAX_DISQUALIFICATIONS_BEFORE_BANNING and \ + self.user.is_banned and self.user.ban_reason == settings.VNOJ_CONTEST_CHEATING_BAN_MESSAGE: + self.user.unban_user() + check_ban.alters_data = True + def set_disqualified(self, disqualified): self.is_disqualified = disqualified self.recompute_results() @@ -600,6 +617,7 @@ def set_disqualified(self, disqualified): self.contest.banned_users.add(self.user) else: self.contest.banned_users.remove(self.user) + self.check_ban() set_disqualified.alters_data = True @property