예제 #1
0
 def get_log(cls,
             context,
             *,
             after=None,
             before=None,
             limit=None,
             challenge=None,
             group=None,
             match=None):
     if after is not None and before is not None:
         raise WrongArguments()
     User.test_permission(context, 'submission.full', 'submission.view')
     queryset = models.Submission.objects.order_by('-pk')
     if after is not None:
         queryset = queryset.filter(pk__lt=after)
     if before is not None:
         queryset = queryset.filter(pk__gt=before).reverse()
     if challenge is not None:
         queryset = queryset.filter(challenge=challenge)
     if group is not None:
         queryset = queryset.filter(group=group)
     if match is not None:
         queryset = queryset.filter(flagclear__isnull=not match)
     queryset = list(
         queryset.values(
             'pk',
             'user',
             'challenge',
             'text',
             'time',
             flag=models.models.F('flagclear__flag'),
         )[slice(limit)])
     if before is not None:
         queryset.reverse()
     return queryset
예제 #2
0
 def update(self, **kwargs):
     User.test_permission(self._context, 'challenge.full')
     old = self._json_all
     self._update(**kwargs)
     new = self._json_all
     for subscriber in self.subscribers:
         subscriber(old, new)
예제 #3
0
 def regen_all(cls, context):
     """重算所有缓存,只有通过命令行提权后才能调用"""
     User.test_permission(context)
     for obj in models.Submission.objects.all():
         try:
             obj.group = User.get(context, obj.user).group
             obj.save()
         except NotFound:
             pass
     for obj in models.FlagClear.objects.all():
         try:
             user = User.get(context, obj.user)
             obj.group = user.group
             challenge = Challenge.get(context, obj.challenge)
             if obj.flag not in range(len(challenge.flags)):
                 raise NotFound
             obj.save()
         except NotFound:
             obj.delete()
     for challenge in Challenge.get_all(context):
         cls._regen_challenge_clear(challenge)
     models.ChallengeFirst.objects.all().delete()
     models.FlagFirst.objects.all().delete()
     cls._refill_first()
     cls._regen_score()
예제 #4
0
 def get_all(cls, context):
     queryset = models.Trigger.objects.order_by('time')
     try:
         User.test_permission(context, 'trigger.full')
     except PermissionRequired:
         queryset = queryset.filter(time__lte=context.time)
     return [cls(context, obj) for obj in queryset]
예제 #5
0
 def create(cls, context, **kwargs):
     User.test_permission(context, 'trigger.full')
     self = cls(context, models.Trigger())
     self._update(**kwargs)
     new = self._json_all
     for subscriber in self.subscribers:
         subscriber(None, new)
     return self
예제 #6
0
 def get(self, request):
     try:
         User.test_authenticated(Context.from_request(request))
     except LoginRequired:
         return redirect('hub')
     return TemplateResponse(request, 'profile.html', {
         'profile_required': User.profile_required,
     })
예제 #7
0
 def delete(self):
     User.test_permission(self._context, 'challenge.full')
     old = self._json_all
     self._obj.expr_set.all().delete()
     self._obj.delete()
     self._obj = None
     for subscriber in self.subscribers:
         subscriber(old, None)
예제 #8
0
 def post(self, request):
     context = Context.from_request(request)
     try:
         User.test_authenticated(context)
     except LoginRequired:
         return redirect('hub')
     for pk in request.POST.getlist('terms'):
         Terms.get(context, pk=pk).agree(request.user.pk)
     return redirect('hub')
예제 #9
0
 def get_board(cls, context, *, limit=None, category=None, group=None):
     if group in User.no_board_groups:
         User.test_permission(context, 'submission.full', 'submission.view')
     return list(
         cls._filter_group(models.Score.objects,
                           group).filter(category=category).order_by(
                               '-score',
                               'time').values('user', 'score',
                                              'time')[slice(limit)])
예제 #10
0
 def create(cls, context, **kwargs):
     User.test_permission(context, 'challenge.full')
     self = cls(context, models.Challenge())
     flags = kwargs.pop('flags')
     self._update(**kwargs)
     self._update(flags=flags)
     new = self._json_all
     for subscriber in self.subscribers:
         subscriber(None, new)
     return self
예제 #11
0
 def save_user(self, request, sociallogin, form=None):
     super().save_user(request, sociallogin, form)
     user = sociallogin.user
     User.create(
         Context(elevated=True),
         group='other',
         user=user,
         email=user.email,
     )
     return user
예제 #12
0
 def flags(self):
     flags = json.loads(self._obj.flags)
     try:
         User.test_permission(self._context, 'challenge.full',
                              'challenge.view')
         return flags
     except PermissionRequired:
         return [{
             'name': flag['name'],
             'score': flag['score'],
         } for flag in flags]
예제 #13
0
 def get_violations(cls, context, *, challenge=None, group=None):
     User.test_permission(context, 'submission.full', 'submission.view')
     queryset = models.FlagViolation.objects
     if challenge is not None:
         queryset = queryset.filter(submission__challenge=challenge)
     if group is not None:
         queryset = queryset.filter(submission__group=group)
     return list(queryset.values(
         'violation_flag', 'violation_user',
         user=models.models.F('submission__user'),
         challenge=models.models.F('submission__challenge'),
         time=models.models.F('submission__time'),
     ))
예제 #14
0
 def get_first(cls, context, *, group=None):
     if group in User.no_board_groups:
         User.test_permission(context, 'submission.full', 'submission.view')
     return {
         'challenges':
         list(
             models.ChallengeFirst.objects.filter(group=group).values(
                 'challenge', 'user', 'time')),
         'flags':
         list(
             models.FlagFirst.objects.filter(group=group).values(
                 'challenge', 'flag', 'user', 'time')),
     }
예제 #15
0
 def regen_all(cls, context):
     """重算所有缓存,只有通过命令行提权后才能调用"""
     User.test_permission(context)
     models.User.objects.all().delete()
     models.Expr.objects.all().delete()
     models.ExprFlag.objects.all().delete()
     for challenge in cls.get_all(context):
         for i, flag in enumerate(challenge.flags):
             if flag['type'] != 'expr':
                 continue
             challenge._obj.expr_set.create(flag_index=i, expr=flag['flag'])
     for user in User.get_all(context):
         if not user.token:
             continue
         cls._add_user(user.pk)
         models.User.objects.create(user=user.pk)
예제 #16
0
 def post(self, request):
     try:
         kwargs = json.loads(request.body)
         kwargs = {k: kwargs[k] for k in kwargs if k in User.update_fields}
         user = User.get(Context.from_request(request), request.user.pk)
         user.update(**kwargs)
         return JsonResponse({})
     except WrongFormat as e:
         return JsonResponse({'error': e.json}, status=400)
예제 #17
0
 def _add_user(cls, user):
     from .expr_flags import expr_flag
     if models.User.objects.filter(user=user).exists():
         return False
     token = User.get(Context(elevated=True), user).token
     for expr_obj in models.Expr.objects.values('expr').distinct():
         models.ExprFlag.objects.create(
             expr=expr_obj['expr'],
             user=user,
             flag=expr_flag(expr_obj['expr'], token),
         )
     return True
예제 #18
0
 def _add_expr(cls, expr):
     from .expr_flags import expr_flag
     if models.Expr.objects.filter(expr=expr).exists():
         return False
     for user_obj in models.User.objects.all():
         token = User.get(Context(elevated=True), user_obj.user).token
         models.ExprFlag.objects.create(
             expr=expr,
             user=user_obj.user,
             flag=expr_flag(expr, token),
         )
     return True
예제 #19
0
def frontend(request):
    return {
        'page':
        Page.get(),
        'user_': (User.get(Context.from_request(request), request.user.pk)
                  if request.user.is_authenticated else None),
        'groups':
        User.groups,
        'debug':
        settings.DEBUG,
        'no_board_groups':
        User.no_board_groups,
    }
예제 #20
0
 def post(self, request):
     if not self.check():
         return redirect('hub')
     eligible = request.POST['eligible']
     if eligible == 'yes':
         UstcEligible.objects.create(user=request.user, eligible=True)
         user = User.get(
             Context.from_request(request).copy(elevated=True),
             request.user.pk)
         user.update(group='ustc')
     elif eligible == 'no':
         UstcEligible.objects.create(user=request.user, eligible=False)
     return redirect('hub')
예제 #21
0
 def login(self, **kwargs):
     account, created = Account.objects.get_or_create(
         provider=self.provider,
         identity=self.normalize_identity(),
     )
     self.on_get_account(account)
     if not account.user:
         account.user = User.create(
             Context(elevated=True),
             group=self.group,
             **kwargs,
         ).user
         account.save()
     login(self.request, account.user, self.backend)
예제 #22
0
 def get_enabled(cls, context):
     User.test_authenticated(context)
     Terms.test_agreed_enabled(context)
     User.test_profile(context)
     try:
         User.test_permission(context, 'challenge.full', 'challenge.view')
     except PermissionRequired:
         Trigger.test_can_view_challenges(context)
     queryset = models.Challenge.objects.filter(enabled=True)
     return [cls(context, obj) for obj in queryset]
예제 #23
0
 def get(self, request):
     context = Context.from_request(request)
     try:
         return TemplateResponse(
             request, 'first.html', {
                 'filters': {
                     'group': request.GET.get('group', None),
                 },
                 'users': {u.pk: u.json
                           for u in User.get_all(context)},
                 'challenges':
                 [c.json for c in Challenge.get_enabled(context)],
             })
     except Error as e:
         messages.error(request, e.message)
         return redirect('hub')
예제 #24
0
 def get(self, request):
     context = Context.from_request(request)
     try:
         return TemplateResponse(
             request, 'board.html', {
                 'filters': {
                     'category': request.GET.get('category', None),
                     'group': request.GET.get('group', None),
                 },
                 'users':
                 {u.pk: u.display_name
                  for u in User.get_all(context)},
             })
     except Error as e:
         messages.error(request, e.message)
         return redirect('hub')
예제 #25
0
 def get(self, request):
     if request.user.is_authenticated:
         if Account.objects.filter(provider='ustc',
                                   user=request.user).exists():
             try:
                 request.user.ustceligible
             except UstcEligible.DoesNotExist:
                 return redirect('ustcprofile')
     context = Context.from_request(request)
     try:
         challenges = Challenge.get_enabled(context)
         challenges = {'value': [obj.json for obj in challenges]}
     except ProfileRequired as e:
         messages.info(request, e.message)
         return redirect('profile')
     except TermsRequired as e:
         messages.info(request, e.message)
         return redirect('terms')
     except Error as e:
         challenges = {'error': e.json}
     try:
         announcement = Announcement.get_latest(context).json
     except NotFound:
         announcement = None
     if request.user.is_authenticated:
         user = User.get(context, request.user.pk)
         if user.group == 'other':
             ranking = Submission.get_user_ranking(context, request.user.pk)
         else:
             ranking = Submission.get_user_ranking(context,
                                                   request.user.pk,
                                                   group=user.group)
     else:
         ranking = {}
     return TemplateResponse(
         request, 'hub.html', {
             'announcement': announcement,
             'challenges': challenges,
             'progress': Submission.get_user_progress(
                 context, request.user.pk),
             'ranking': ranking,
             'clear_count': Submission.get_clear_count(context),
         })
예제 #26
0
 def get(cls, context, pk):
     queryset = models.Challenge.objects.all()
     try:
         User.test_permission(context, 'challenge.full', 'challenge.view')
     except PermissionRequired:
         User.test_authenticated(context)
         Terms.test_agreed_enabled(context)
         User.test_profile(context)
         Trigger.test_can_view_challenges(context)
         queryset = queryset.filter(enabled=True)
     try:
         return cls(context, queryset.get(pk=pk))
     except models.Challenge.DoesNotExist:
         raise NotFound('题目不存在')
예제 #27
0
 def submit(cls, context, user, challenge, text):
     if context.user.pk != user:
         User.test_permission(context)
     if len(text) > 200:
         raise WrongFormat('Flag 不应超过 200 个字符')
     user = User.get(context, user)
     challenge = Challenge.get(context, challenge)
     try:
         latest = (models.Submission.objects.filter(
             user=user.pk, challenge=challenge.pk).latest('time'))
     except models.Submission.DoesNotExist:
         pass
     else:
         if latest.time + timedelta(seconds=10) > context.time:
             raise SlowDown('提交过于频繁,请 10 秒后再试')
     obj = models.Submission.objects.create(
         user=user.pk,
         group=user.group,
         challenge=challenge.pk,
         text=text,
         time=context.time,
     )
     matches, violations = challenge.check_flag_with_violations(text)
     queryset = models.FlagClear.objects.filter(user=user.pk,
                                                challenge=challenge.pk)
     flags = {i.flag for i in queryset}
     match_flags = {i['index'] for i in matches}
     for flag in match_flags - flags:
         models.FlagClear.objects.create(
             submission=obj,
             user=user.pk,
             group=user.group,
             challenge=challenge.pk,
             flag=flag,
             time=context.time,
         )
         if user.group not in User.no_score_groups:
             models.FlagFirst.objects.get_or_create(
                 challenge=challenge.pk,
                 flag=flag,
                 group=None,
                 defaults={
                     'user': user.pk,
                     'time': context.time
                 },
             )
         models.FlagFirst.objects.get_or_create(
             challenge=challenge.pk,
             flag=flag,
             group=user.group,
             defaults={
                 'user': user.pk,
                 'time': context.time
             },
         )
     for f, u in violations:
         models.FlagViolation.objects.create(
             submission=obj,
             violation_flag=f['index'],
             violation_user=u,
         )
     if match_flags - flags:
         if (flags | match_flags).issuperset(range(len(challenge.flags))):
             models.ChallengeClear.objects.create(
                 user=user.pk,
                 group=user.group,
                 challenge=challenge.pk,
                 time=context.time,
             )
             if user.group not in User.no_score_groups:
                 models.ChallengeFirst.objects.get_or_create(
                     challenge=challenge.pk,
                     group=None,
                     defaults={
                         'user': user.pk,
                         'time': context.time
                     },
                 )
             models.ChallengeFirst.objects.get_or_create(
                 challenge=challenge.pk,
                 group=user.group,
                 defaults={
                     'user': user.pk,
                     'time': context.time
                 },
             )
         score = sum(i['score'] for i in matches if i['index'] not in flags)
         cls._add_score(user.pk, user.group, context.time, score,
                        challenge.category)
     return matches
예제 #28
0
 def get_all(cls, context):
     User.test_permission(context, 'challenge.full', 'challenge.view')
     return [cls(context, obj) for obj in models.Challenge.objects.all()]
예제 #29
0
 def get(cls, context, pk):
     User.test_permission(context, 'trigger.full')
     try:
         return cls(context, models.Trigger.objects.get(pk=pk))
     except models.Trigger.DoesNotExist:
         raise NotFound()
예제 #30
0
 def delete(self):
     User.test_permission(self._context, 'trigger.full')
     self._obj.delete()
     self._obj = None